Java руководство для начинающих - Шилдт Герберт (2012)
-
Год:2012
-
Название:Java руководство для начинающих
-
Автор:
-
Жанр:
-
Оригинал:Английский
-
Язык:Русский
-
Издательство:Вильямс
-
Страниц:316
-
ISBN:978-5-8459-1770-6
-
Рейтинг:
-
Ваша оценка:
Java руководство для начинающих - Шилдт Герберт читать онлайн бесплатно полную версию книги
Рассмотрим для примера следующую ситуацию. В потоке Т выполняется синхронизированный метод, которому необходим доступ к ресурсу R. Этот ресурс временно недоступен. Что должен предпринять поток т? Если он будет ожидать в цикле освобождения ресурса R, объект будет по-прежнему заблокирован и другие потоки не смогут обратиться к нему. Такое решение малопригодно, поскольку оно сводит на нет все преимущества программирования в многопоточной среде. Намного лучше, если поток Т временно разблокирует объект и позволит другим потокам воспользоваться его методами. Когда ресурс R станет доступным, поток т получит об этом уведомление и возобновит свое исполнение. Но для того чтобы такое решение можно было реализовать, необходимы средства взаимодействия потоков, с помощью которых один поток мог бы уведомить другой поток о том, что он приостановил свое исполнение, а также получить уведомление о том, что его исполнение может быть возобновлено. Для организации подобного взаимодействия потоков в Java предусмотрены методы wait (), notify () и notifyAll ().
Эти методы реализованы в классе Object, поэтому они доступны для любого объекта. Но обратиться к ним можно только из синхронизированного контекста. А применяются они следующим образом. Когда поток временно приостанавливает свое исполнение, он вызывает метод wait (). При этом поток переходит в состояние ожидания и монитор данного объекта освобождается, позволяя другим потокам использовать объект. Впоследствии ожидающий поток возобновит свое выполнение, когда другой поток войдет в тот же самый монитор и вызовет метод notify () или notifyAll ().
В классе Object определены различные формы объявления метода wait (), как показано ниже.
final void wait() throws InterruptedException
final void wait(long миллисекунд) throws InterruptedException
final void wait(long миллисекунд, int наносекунд) throws InterruptedException
В первой своей форме метод wait () переводит поток в режим ожидания до поступления уведомления. Во второй форме метода организуется ожидание уведомления или до тех пор, пока не истечет указанный период времени. А третья форма позволяет точнее задавать период времени в наносекундах.
Ниже приведены общие формы объявления методов notify () и notifyAll ().
final void notifyO
final void notifyAll()
При вызове метода notify () возобновляется исполнение одного ожидающего потока. А метод notifyAll () уведомляет все потоки об освобождении объекта, и тот поток, который имеет наивысший приоритет, получает доступ к объекту.
Прежде чем рассматривать конкретный пример, демонстрирующий применение метода wait (), необходимо сделать важное замечание. Несмотря на то что метод wait () должен переводить поток в состояние ожидания до тех пор, пока не будет вызван метод notify () или notifyAll (), иногда поток выводится из состояния ожидания вследствие так называемой ложной активизации. Условия для ложной активизации сложны, возникают редко, а их обсуждение выходит за рамки этой книги. Но в компании Oracle рекомендуют учитывать вероятность проявления ложной активизации и помещать вызов метода wait () в цикл. В этом цикле должно проверяться условие, по которому поток переводится в состояние ожидания. Именно такой подход и применяется в рассматриваемом ниже примере.
Пример применения методов wait() и notify()