Ответ
Нет, вызов wait() вне синхронизированного контекста приведет к IllegalMonitorStateException.
Причина: Перед тем как перейти в состояние ожидания и освободить монитор, поток должен этот монитор захватить. Это фундаментальное требование механизма wait/notify.
Некорректный вызов:
Object monitor = new Object();
monitor.wait(); // IllegalMonitorStateException!
Корректный шаблон использования (шаблон "Guarded Blocks"):
synchronized (monitor) {
while (!someCondition) { // Всегда используйте цикл, а не if!
monitor.wait(); // 1. Освобождает монитор 'monitor'
// 2. Переходит в состояние WAITING
// 3. После пробуждения заново захватывает монитор
}
// Выполнение работы, когда условие выполнено
}
Ключевые моменты:
- Цикл
while: Необходим для защиты от ложных пробуждений (spurious wakeups), которые разрешены спецификацией JVM. - Атомарность: Синхронизация гарантирует, что проверка условия
!someConditionи вызовwait()происходят как одна неделимая операция. Без этого другой поток мог бы изменить условие и вызватьnotify()в промежутке между проверкой и ожиданием, что привело бы к вечному ожиданию.