Вопрос проверяет знание правил использования механизмов ожидания и уведомления в Java.
wait() и notify() можно вызывать только внутри синхронизированного блока или метода. Поток должен владеть монитором объекта, на котором вызывается метод. В противном случае будет выброшено исключение. Это правило гарантирует корректную работу синхронизации.
Правильное использование wait() и notify() жестко связано с понятием монитора.
Определение:
Поток должен владеть монитором объекта, чтобы вызывать wait() или notify() для этого объекта.
Это означает:
код должен быть внутри synchronized
синхронизация должна выполняться на том же объекте
synchronized (lock) {
lock.wait();
}
Нарушение правила:
lock.wait(); // IllegalMonitorStateException
Перед объяснением причины важно понимать, что монитор управляет доступом к объекту.
предотвращаются гонки данных
гарантируется согласованность состояния
поток корректно освобождает монитор при ожидании
вызов wait() не на том объекте
синхронизация на одном объекте, а ожидание на другом
вызов notify() вне synchronized
wait() и notify() всегда должны вызываться внутри синхронизированного блока на том же объекте, чей монитор используется.