На каком объекте можно вызвать wait() внутри synchronized-метода в Java?

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

Ответ

Метод wait() можно вызвать только на том же объекте, который используется в качестве монитора для synchronized-блока или метода.

Почему? Потому что wait() освобождает блокировку этого конкретного объекта-монитора и переводит текущий поток в состояние ожидания, пока другой поток не вызовет notify() или notifyAll() на том же объекте.

Пример:

public class Example {
    private final Object lock = new Object();

    public void synchronizedMethod() throws InterruptedException {
        synchronized (lock) { // Монитор - объект 'lock'
            // wait() вызывается на том же объекте 'lock'
            lock.wait(); // Корректно
            // this.wait(); // Ошибка, если synchronized на 'lock', а не на 'this'
        }
    }
}

Правило: synchronized(monitor) { monitor.wait(); }