Спецификация Java 11: 17.2. Набор ожиданий и уведомления

Каждый объект, помимо связанного монитора, имеет связанный набор ожиданий (wait set). Набор ожиданий - это набор потоков.

Когда объект создается впервые, его набор ожидания пуст. Элементарные действия, которые добавляют потоки и удаляют потоки из наборов ожидания, являются атомарными. Наборы ожидания управляются исключительно с помощью методов Object.wait, Object.notify и Object.notifyAll.

На манипуляции с наборами ожидания также может влиять статус прерывания потока и методы класса Thread, работающие с прерыванием. Кроме того, методы класса Thread для сна и присоединения к другим потокам имеют свойства, производные от свойств ожидания и уведомлений.

17.2.1. Ожидание (wait)

Действия ожидания происходят при вызове метода wait() или форм wait(long millisecs) и wait(long millisecs, int nanosecs).

Вызов wait(long millisecs) с нулевым параметром или вызов wait(long millisecs, int nanosecs) с двумя нулевыми параметрами эквивалентен вызову wait().

Поток нормально возвращается из ожидания, если он возвращается без исключения InterruptedException.

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

  • Если n равно нулю (т. е. поток t еще не имеет блокировки для цели m), то генерируется исключение IllegalMonitorStateException.
  • Если это wait с временем и аргумент nanosecs не находится в диапазоне 0-999999 или аргумент millisecs отрицательный, возникает исключение IllegalArgumentException.
  • Если поток t прерывается, возникает исключение InterruptedException, а статус прерывания t устанавливается в значение false.
  • В противном случае имеет место следующая последовательность:
    1. Поток t добавляется в набор ожидания объекта m и выполняет n действий разблокировки на m.
    2. Поток t не выполняет никаких дальнейших инструкций, пока он не будет удален из набора ожидания m. Поток может быть удален из набора ожидания из-за любого из следующих действий и возобновится через некоторое время:

      • Действие уведомления (notify), выполняемое на m, в котором t выбрано для удаления из набора ожидания.
      • Действие notifyAll, выполняемое на m.
      • Прерывание (interrupt) выполняется на t.
      • Если это wait с временем ожидания, внутреннее действие, удаляющее t из набора ожидания m, которое происходит по истечении, по крайней мере, millisecs миллисекунд плюс nanosecs наносекунд с начала этого действия ожидания.
      • Внутреннее действие реализации. Реализациям разрешено, хотя и не рекомендуется, выполнять "ложные пробуждения", то есть удалять потоки из наборов ожидания и, таким образом, разрешать возобновление без явных инструкций для этого.

        Обратите внимание, что это положение требует практики кодирования Java с использованием wait только внутри циклов, которые завершаются только тогда, когда выполняется какое-то логическое условие, которого ожидает поток.

      Каждый поток должен определять порядок событий, которые могут привести к его удалению из набора ожидания. Этот порядок не обязательно должен соответствовать другим порядкам, но поток должен вести себя так, как если бы эти события произошли в этом порядке.

      Например, если поток t находится в наборе ожидания для m, а затем происходит как прерывание t, так и уведомление m, должен быть порядок этих событий. Если считается, что прерывание произошло первым, тогда t в конечном итоге вернется из ожидания, выбрасывая InterruptedException, и какой-то другой поток в ожидании, установленном для m (если таковой существует на момент уведомления), должен получить уведомление. Если считается, что уведомление появилось первым, то в конечном итоге t вернется в обычном режиме из ожидания с ожидающим прерыванием.

    3. Поток t выполняет n действий блокировки на m.
    4. Если поток t был удален из набора ожидания m на шаге 2 из-за прерывания, тогда состояние прерывания t устанавливается в false, и метод ожидания генерирует InterruptedException.

Читайте также:


Комментарии

Популярные сообщения из этого блога

Методы класса Object в Java

Как получить текущий timestamp в Java

Основные опции JVM для повышения производительности и отладки