2014-11-03 2 views
0

Рассмотрим следующий код:Как реализовать спинлока, чтобы избежать блокировки

// Below block executed by thread t1 
synchronized(obj) { 
    obj.wait(0); 
} 

// This block executed by thread t2 
synchronized(obj) { 
    obj.notify(); 
} 

Я понимаю, что в коде выше, если t1 взял владение синхронизированного блока и в то же время, если нить t2 пытается принять синхронизированный блок , то t2 подходит для ожидания ядра. Я хочу, чтобы избежать этой ситуации и вращать t2 перед блоком до t1 вызывает ожидания и оставляет право собственности на блок. Это возможно?

+0

Пожалуйста, приложите больше усилий для форматирования своего сообщения, прежде чем нажимать submit - используйте предварительный просмотр, чтобы посмотреть, как будет выглядеть сообщение, и только отправьте его, когда он посмотрит, как вы хотите, чтобы он выглядел, если * вы * ответили на вопрос , –

+6

Кроме того, есть ли у вас доказательства того, что это действительно вызывает проблему в вашем коде? Блокировка спина очень редко является правильным решением - и имейте в виду, что 't1' отменит блокировку, как только она называет' wait() ', поэтому окно возможностей для блокировки t2 действительно очень мало. –

+0

Почему вы хотите это сделать? Вместо этого в одном потоке, ожидающем блокировки, у вас будет один поток, ожидающий блокировки, и в то же время теряющий процессорные циклы. –

ответ

1

JVM не должен внедрять запись в заблокированный синхронизированный блок в качестве жесткого блока и контекстного переключателя. Он имеет возможность использовать более легкие весовые методы, такие как блокировки спина. Фактически, JVM Oracle идет на несколько длин, чтобы избежать блокировки. Таким образом, вы можете обнаружить, что JVM уже сделала эту оптимизацию для вас. И если это не так, возможно, это связано с тем, что у JVM есть доказательства того, что блокировка спина будет плохой идеей.

+0

Спасибо Raedwald, можете ли вы поделиться ссылками, которые предлагают это. –

0

Да, вы можете делать то, что хотите.

Реализация интерфейса java.util.concurrent.locks.Lock (такие, как ReentrantLock) позволяет занят-ожидать блокировки с помощью метода tryLock (вызывается из цикла).

Для реализации wait и notify функциональности, вы вызываете метод newCondition на Lock для получения Condition объекта. Интерфейс Condition имеет методы await и signal/signalAll, которые работают аналогично wait и notify/notifyAll.

Смежные вопросы