Ответ
Метод wait() — это основа механизма кооперативной синхронизации потоков (wait-notify). Он приостанавливает выполнение текущего потока до тех пор, пока другой поток не вызовет notify() или notifyAll() на том же объекте-мониторе.
Ключевые принципы:
- Вызов только в synchronized-блоке:
wait(),notify(),notifyAll()можно вызывать только внутри критической секции, синхронизированной на том же объекте (thisили явном lock). - Освобождение монитора: При вызове
wait()поток освобождает монитор, позволяя другим потокам войти в synchronized-секцию. - Пробуждение и повторный захват: После вызова
notify()/notifyAll()поток просыпается и пытается повторно захватить монитор, прежде чем продолжить выполнение.
Стандартный шаблон использования (идиома «охраняемого цикла»):
synchronized (sharedLock) {
while (!condition) { // Всегда проверяйте условие в цикле!
sharedLock.wait(); // Ждем, пока условие не станет true
}
// Выполняем работу, когда условие выполнено
// ...
}
// В другом потоке:
synchronized (sharedLock) {
condition = true;
sharedLock.notifyAll(); // Пробуждаем все ожидающие потоки
}
Важные нюансы:
- Spurious Wakeup: Поток может проснуться без вызова
notify. Поэтому проверка условия всегда должна быть в цикле. notify()vsnotifyAll():notify()будит один случайный поток,notifyAll()— все. ИспользуйтеnotifyAll()для большей предсказуемости, если потоки ждут разных условий.- Применение: Реализация паттернов Producer-Consumer, пулов ресурсов, ограничителей (throttling) и других сценариев взаимодействия потоков.