Главная » Java » Механизмы ожидания и оповещения Java

0

 

Существуют три формы методов ожидания и две – оповещения. Все они реализованы в составе класса Object и снабжены модификатором final, препятствующим их переопределению в производных классах.

public final void wait(long timeout) throws InterruptedException Текущий поток ожидает наступления одного из четырех событий: вызван метод notify объекта и потоку следует продолжить работу; вызван метод notifyALL объекта; истек промежуток времени, заданный параметром timeout; поток вызвал собственный метод interrupt. Значение timeout выражается в миллисекундах. Если оно равно нулю, метод будет выполняться неопределенное время до получения уведомления, посланного от notify или notifyALL. На время цикла ожидания блокировка объекта освобождается и автоматически устанавливается непосредственно перед завершением выполнения wait, независимо от того, как и почему ожидание прекращается. Если работа wait завершается в результате вызова метода interrupt, выбрасывается исключение типа InterruptedException.

public final void wait(long timeout, int nanos)

throws InterruptedException

Более чувствительная версия метода. Величина интервала ожидания складывается из двух составляющих: timeout (выраженной в миллисекундах) и nanos (в наносекундах). Величина nanos должна находиться в промежутке 0-999999.

public final void wait() throws InterruptedException Метод аналогичен первому варианту при условии wait (0).

public final void notifyAll()

Оповещает все потоки, ожидающие выполнения условия. Перед выходом из состояния ожидания потоки восстанавливают блокировку объекта.

public final void notify()

Оповещает, самое большее, один из потоков, ожидающих выполнения условия. Выбрать поток, подлежащий оповещению, нельзя, поэтому метод следует применять только в тех случаях, когда вы знаете, какой поток и когда находится в состоянии ожидания. Если хотя бы один из этих факторов не известен, надлежит использовать метод оповещения notifyAll.

Если в момент вызова notifyALL или notify нет потоков, находящихся в состоянии ожидания, уведомление, посланное методами, не запоминается. Если поток переходит в стадию. ожидания периодически, прежние обращения к методам оповещения на него не воздействуют. Результативными оказываются только те уведомления, которые посылаются после вызова потоком метода wait.

Все рассмотренные методы могут вызываться только из синхронизированного кода при использовании блокировки соответствующего объекта. Обращение к методам осуществляется либо непосредственно из синхронизированного кода, либо косвенно, из тела метода, вызванного из такого кода. Если предпринимается попытка использования методов объекта, право на блокировку которого отсутствует, генерируется исключение типа IllegalMonitorstateException.

Если выполнение метода wait завершается ввиду истечения периода ожидания, поток не в состоянии "узнать" об этом каким-либо иным способом, кроме как в результате оповещения. Если потоку необходимо обладать данными о том, Подошло ли к концу время ожидания, он должен сам предусмотреть средства их Получения. Задание ограниченного периода ожидания можно рассматривать как защитную меру, позволяющую справляться с ситуациями, когда некоторое условие должно быть удовлетворено, но по каким-то причинам (вероятно, связанным с нарушением работоспособности другого потока) этого не происходит.

В некоторых реализациях допускаются также так называемые ложные срабатывания (spurious wakeups), когда поток завершает выполнение wait по причинам, не связанным ни с одним из событий, таких как истечение периода ожиданиЯ, прерывание методом interrupt или получение уведомления от метода оповещения. Это еще одна причина, по которой вызов wait следует помещать в тело цикла, проверяющего условие ожидания.

Упражнение 10.6. Напишите программу, которая каждую секунду отображает на экране данные о времени, прошедшем от начала сессии, а другой ее поток выходит сообщение каждые пятнадцать секунд. Предусмотрите возможность ежесекундного оповещения потока, воспроизводящего сообщение, потоком, Отсчитывающим время. Не внося изменений в код потока-"хронометра", добавьте еще один поток, который выводит на экран другое сообщение каждые семь секунд.

 

Источник: Арнолд, Кен, Гослинг, Джеймс, Холмс, Дэвид. Язык программирования Java. 3-е изд .. : Пер. с англ. – М. : Издательский дом «Вильяме», 2001. – 624 с. : ил. – Парал. тит. англ.

По теме:

  • Комментарии