Спецификация Java 11: 17.2.2. Уведомление. 17.2.3. Прерывания
17.2.2. Уведомление
Действия уведомления происходят при вызове методов notify и notifyAll.
Пусть поток t будет потоком, выполняющим любой из этих методов для объекта m, и пусть n будет количеством действий блокировки t на m, которые не были сопоставлены действиями разблокировки. Происходит одно из следующих действий:
-
Если n равно нулю, возникает исключение IllegalMonitorStateException.
Это тот случай, когда поток t еще не имеет блокировки для цели m.
-
Если n больше нуля и это действие уведомления, то если набор ожидания m не пуст, поток u, который является членом текущего набора ожидания m, выбирается и удаляется из набора ожидания.
Нет никакой гарантии, какой поток в наборе ожидания выбран. Это удаление из набора ожидания позволяет возобновить u в действии ожидания. Обратите внимание, однако, что действия блокировки u при возобновлении не могут быть успешными до тех пор, пока t полностью не разблокирует монитор для m.
-
Если n больше нуля и это действие notifyAll, то все потоки удаляются из набора ожидания m и, таким образом, возобновляются.
Обратите внимание, однако, что только один из них будет блокировать требуемый монитор во время возобновления ожидания.
17.2.3. Прерывания
Действия прерывания происходят при вызове Thread.interrupt, а также методов, определенных для его поочередного вызова, таких как ThreadGroup.interrupt.
Пусть t будет потоком, вызывающим u.interrupt для некоторого потока u, где t и u могут быть одинаковыми. Это действие приводит к установке статуса прерывания u в значение true.
Кроме того, если существует некоторый объект m, набор ожидания которого содержит u, то u удаляется из набора ожидания m. Это позволяет u возобновить действие ожидания, и в этом случае это ожидание после повторной блокировки монитора m вызовет исключение InterruptedException.
Вызовы Thread.isInterrupted могут определять состояние прерывания потока. Статический метод Thread.interrupted может быть вызван потоком для наблюдения и очистки своего собственного состояния прерывания.
17.2.4. Взаимодействие ожидания, уведомления и прерывания
Вышеупомянутые спецификации позволяют нам определить несколько свойств, связанных с взаимодействием ожидания, уведомления и прерывания.
Если поток одновременно получает уведомление и прерывается во время ожидания, он может:
- вернуться в обычном режиме из ожидания, пока еще есть ожидающее прерывание (другими словами, вызов Thread.interrupted вернет true)
- вернуться из ожидания, выбрасывая InterruptedException
Поток может не сбросить свое состояние прерывания и нормально вернуться из вызова для ожидания.
Точно так же уведомления не могут быть потеряны из-за прерываний. Предположим, что набор s потоков находится в наборе ожидания объекта m, а другой поток выполняет уведомление на m. Тогда либо:
- по крайней мере один поток в s должен нормально вернуться из ожидания, или
- все потоки в s должны выйти из ожидания, выбрасывая InterruptedException
Обратите внимание: если поток одновременно прерывается и просыпается с помощью уведомления, и этот поток возвращается из ожидания, создавая InterruptedException, то должен быть уведомлен какой-либо другой поток в наборе ожидания.
Читайте также:
- Спецификация Java 11: Глава 17. Потоки и блокировки
- Спецификация Java 11: 17.1. Синхронизация
- Спецификация Java 11: 17.2. Набор ожиданий и уведомления
Комментарии
Отправить комментарий