JavaRush /Курсы /Модуль 2. Java Core /Знакомство с методами wait, notify, notifyAll

Знакомство с методами wait, notify, notifyAll

Модуль 2. Java Core
9 уровень , 2 лекция
Открыта

— Привет, Амиго!

— Привет, Риша!

— Я познакомлю тебя с методами wait, notify, notifyAll класса Object.

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

— Хорошо.

— Эти методы были придуманы как часть механизма синхронизации нитей.

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

— Я помню, это делается с помощью ключевого слова synchronized.

— Правильно. Обычно такой код выглядит примерно так:

public void print()
{
 Object monitor = getMonitor();
 synchronized(monitor)
 {
  System.out.println("text");
 }
}

Помнишь, как это работает?

— Ага. Если две нити одновременно вызовут метод print(), то одна из них войдет в блок, помеченный synchronized, и заблокирует monitor, поэтому вторая нить будет ждать, пока монитор не освободится.

— Правильно. Как только нить входит в блок, помеченный synchronized, то объект-монитор помечается как занятый, и другие нити будут вынуждены ждать освобождения объекта-монитора. Один и тот же объект-монитор может использоваться в различных частях программы.

— Кстати, почему – монитор?

— Монитором принято называть объект, который хранит состояние занят/свободен.

Вот тут и вступают в дело методы wait и notify.

Собственно, методов как таковых всего два. Остальные – это лишь модификации этих методов.

Теперь разберемся, что же такое метод wait и зачем он нужен.

Иногда в программе может оказаться такая ситуация, что нить вошла в блок кода synchronized, заблокировала монитор и не может работать дальше, т.к. каких-то данных еще не хватает: например, файл который она должна обработать еще не загрузился или что-нибудь в таком духе.

Мы же можем просто подождать, когда файл скачается. Можно просто в цикле проверять – если файл еще не скачался – спать, например, секунду и опять проверять и т.д.

Примерно так:

while(!file.isDownloaded())
{
 Thread.sleep(1000);
}
processFile(file);

Но в нашем случае такое ожидание слишком дорого. Т.к. наша нить заблокировала монитор, то другие нити вынуждены тоже ждать, хотя их данные для работы могут быть уже готовы.

Для решения этой проблемы и был придуман метод wait(). Вызов этого метода приводит к тому, что нить освобождает монитор и «становится на паузу».

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

Часто встречаются ситуации, когда в блок synchronized зашла нить, вызвала там wait, освободила монитор.

Затем туда вошла вторая нить и тоже стала на паузу, затем третья и так далее.

— А как же нить снимется с паузы?

— Для этого есть второй метод – notify.

Методы notify/notifyAll можно вызвать у объекта-монитора и только, когда этот монитор занят – т.е. внутри блока synchronized. Метод notifyAll снимает с паузы все нити, которые стали на паузу с помощью данного объекта-монитора.

Метод notify «размораживает» одну случайную нить, метод notifyAll – все «замороженные» нити данного монитора.

— Очень интересно, спасибо Риша.

— Рад, что тебе нравится, Амиго!

Есть еще модификации метода wait():

Метод wait() Пояснение
void wait(long timeout)
Нить «замерзает», но через переданное количество миллисекунд автоматически «размораживается».
void wait(long timeout, int nanos)
Нить «замерзает», но через переданное количество миллисекунд и наносекунд автоматически «размораживается».

Это, как еще говорят, wait с таймаутом. Метод работает как обычный wait, но если указанное время прошло, а нить никто не снял с паузы – она активируется сама.

Комментарии (21)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Станислав Уровень 48
2 октября 2025
Вы тоже помните то, чего не было?)
Alexander Уровень 79
30 сентября 2025
ощущение что проспал половину лекции и теперь проснувшись, пытаешься понять, что происходит.
30 сентября 2025
"Помнишь как это работает?" - ну да, конечно. Как можно помнить то, чего не было?!
Людмила Уровень 79
29 сентября 2025
После прочиения лекции по ссылке, стало немного легче читать про метод synchronized https://www.google.com/url?sa=t&source=web&rct=j&opi=89978449&url=https://javarush.com/groups/posts/1994-sinkhronizacija-potokov-operator-synchronized&ved=2ahUKEwjO88Ln1f2PAxVTAxAIHTUUOVgQFnoECBsQAQ&usg=AOvVaw0v8Ug4Bs4cEIEIfFx5drOu
Владимир Уровень 40
1 августа 2025
Структура курса утеряна - не ясно откуда до этого момента студенты должны знать про метод synchronized - он нигде не объяснялся. И стоит переименовать во всех лекция не понятные и никем не используемые "нити" в понятные и используемые всеми потоки.
Serge Menko Уровень 58
21 ноября 2024
а где раньше про synchronized рассказывали?оО
25 октября 2024
Ну хоть бы переместили эту лекцию в уровень с нитями... Либо переписали так, чтобы все уровни подписок понимали её...
Артем Иевлев Уровень 115
26 ноября 2024
Не могу не согласиться
Булат Уровень 109
28 сентября 2024
как будто какую то часть лекции просто пропустили. что такое синхронизед?!, от слова совсем не понимейшн
Денис Уровень 68
11 февраля 2025
Абсолютли
Инна Уровень 105
22 июня 2024
такое ощущение, что мы пропустили разговоры Амиго и Риши про нити, которые они разговаривали без нас когда-то в прошлом)
Andre Уровень 97
6 марта 2024
И зачем это давать народу? База еще не подготовлена