Java: все ли мониторы выпущены, когда поток ждет объекта?
Прежде чем поток может wait
на объект, он должен получить монитор на этом объекте. Затем монитор отпускается, и поток пытается повторно получить его после его пробуждения.
Но что происходит с другими мониторами, когда поток выполняется, когда он вызывает wait
?
Рассмотрим следующий пример:
Object a = // ...
Object b = // ...
synchronized(a)
{
synchronized(b)
{
b.wait();
// continue
}
}
Когда поток вызывает b.wait()
, он отпустит блокировки как на a
, так и на b
или только b
?
Ответы
Ответ 1
Только b
.
Авторитарным источником этих вопросов является спецификация языка Java. Соответствующий раздел в этом случае 17.8 Wait Sets and Notification:
Пусть поток t - это поток , выполняющий метод wait на объекте m, и пусть n - количество действий блокировки по t на m, которые не были сопоставлены действиями разблокировки. Выполняется одно из следующих действий.
Ответ 2
Из документации API Java класса объекта:
Текущий поток должен владеть этим монитор объекта. Выпуски потоков владение этим монитором и ждет пока другой поток не сообщит о потоках ожидание на этом объекте монитора просыпаться либо путем вызова уведомлять метод или метод notifyAll. Затем поток ждет, пока он не сможет повторно получить право собственности на монитор и возобновляет выполнение.
Итак, вызов b.wait()
освобождает блокировку только на b
.
Ответ 3
Только AFAIK b. Это классический источник тупиков.