Ответ
Метод wait() (наследуемый от класса Object) используется для приостановки выполнения текущего потока до тех пор, пока другой поток не вызовет notify() или notifyAll() на том же объекте-мониторе. Это основа механизма межпоточного взаимодействия (cooperative concurrency).
Ключевые правила:
- Синхронизация:
wait(),notify(),notifyAll()должны вызываться только внутри синхронизированного блока (synchronized) на одном и том же объекте. - Освобождение монитора: При вызове
wait()поток освобождает блокировку (монитор) объекта и переходит в состояние ожидания. - Пробуждение: Поток может быть разбужен вызовом
notify()(пробуждает один случайный поток) илиnotifyAll()(пробуждает все потоки) из другого потока.
Типичный шаблон "Producer-Consumer":
public class SharedBuffer {
private final Queue<Integer> queue = new LinkedList<>();
public synchronized void produce(int value) throws InterruptedException {
while (queue.size() >= 10) {
wait(); // Ждем, пока потребитель не освободит место
}
queue.add(value);
notifyAll(); // Сообщаем потребителям, что данные появились
}
public synchronized int consume() throws InterruptedException {
while (queue.isEmpty()) {
wait(); // Ждем, пока производитель не добавит данные
}
int value = queue.poll();
notifyAll(); // Сообщаем производителям, что место освободилось
return value;
}
}
Важно: Всегда вызывайте wait() в цикле, проверяющем условие (из-за возможности ложного пробуждения - spurious wakeup). Используйте wait(long timeout) для ограничения времени ожидания.