2015-02-19 2 views
0

Я изучаю параллелизм Java, и я нашел один интересный вопрос, на который я не могу ответить.Может ли другой поток вводить монитор, а ожидающий уведомляется?

Например, у меня есть три потока: ThreadA, ThreadB и ThreadC. ThreadA входит в монитор и вызывает метод wait(). Затем ThreadB входит в тот же монитор, вызывает метод notify() и продолжает владеть монитором в течение некоторого периода времени. Пока ThreadB владеет монитором, ThreadC также пытается получить монитор. Мой вопрос: сможет ли ThreadC получить монитор раньше, чем ThreadA, когда ThreadB выпустит его или нет? Если это возможно, почему? Какие условия следует соблюдать, чтобы воспроизвести его?

ответ

2

В соответствии с Javadoc на Object.notify():

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

Таким образом, существует вероятность, что ThreadC владеет монитором до ThreadA. Определенный порядок, в котором ни один из потоков не входит/не получает монитор, и не существует механизма приоритета или справедливости для стандартной синхронизации. Все, что действительно гарантирует, - это то, что для данного объекта блокировки только в потоке будет находиться в синхронизированном блоке сразу.

Учитывая этот факт, тщательные соображения дизайна должны учитывать то, как потоки получают замок и как долго. Поток, который неоднократно пытается получить блокировку (приобретать, а затем освобождать, а затем приобретать снова), может привести к тому, что другой поток будет заблокирован неограниченно (называемый потоковым голоданием).

Использование ReentrantLock с политикой справедливости может частично преодолеть эту проблему при некоторой производительности (ее немного медленнее традиционной синхронизации).

+0

Большое спасибо, это помогает мне! – RuslanSh

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