Подтвердить что ты не робот

Java: все ли мониторы выпущены, когда поток ждет объекта?

Прежде чем поток может wait на объект, он должен получить монитор на этом объекте. Затем монитор отпускается, и поток пытается повторно получить его после его пробуждения.

Но что происходит с другими мониторами, когда поток выполняется, когда он вызывает wait?

Рассмотрим следующий пример:

   Object a = // ...
   Object b = // ...

   synchronized(a)
   {
       synchronized(b)
       {
           b.wait();
           // continue
       }
   }

Когда поток вызывает b.wait(), он отпустит блокировки как на a, так и на b или только b?

4b9b3361

Ответ 1

Только b.

Авторитарным источником этих вопросов является спецификация языка Java. Соответствующий раздел в этом случае 17.8 Wait Sets and Notification:

Пусть поток t - это поток , выполняющий метод wait на объекте m, и пусть n - количество действий блокировки по t на m, которые не были сопоставлены действиями разблокировки. Выполняется одно из следующих действий.

  • [...]
  • В противном случае происходит следующая последовательность:

    • Thread t добавляется в набор ожиданий объекта m и выполняет n разблокированных действий на m.
    • [...]

Ответ 2

Из документации API Java класса объекта:

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

Итак, вызов b.wait() освобождает блокировку только на b.

Ответ 3

Только AFAIK b. Это классический источник тупиков.