Можно ли вызвать метод notify() у объекта вне блока synchronized в Java?

«Можно ли вызвать метод notify() у объекта вне блока synchronized в Java?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Нет, вызов 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.