Ответ
Нет, вызов notify() или notifyAll() вне синхронизированного контекста приведет к IllegalMonitorStateException.
Причина: Поток должен владеть монитором объекта (т.е. находиться внутри блока synchronized по этому объекту), чтобы разбудить другие потоки, ожидающие на этом же мониторе.
Пример, вызывающий исключение:
Object lock = new Object();
lock.notify(); // IllegalMonitorStateException!
Правильный подход:
Object lock = new Object();
// Поток-уведомитель
synchronized (lock) {
// ... некоторая работа, изменяющая общее условие
lock.notify(); // Корректно: поток владеет монитором 'lock'
}
Объяснение "почему": Требование синхронизации гарантирует, что проверка условия (например, while (!condition)) и последующий вызов wait() или notify() являются атомарными. Это предотвращает классическую race condition, когда поток уведомляет до того, как другой поток начал ожидание, что может привести к "потере" сигнала и вечному deadlock.