Wait(), notify() и notifyAll() и IllegalMonitorStateException

Wait(), notify() и notifyAll() и IllegalMonitorStateException

Методы wait(), notify() и notifyAll() должны вызываться на тех объектах, по которым производилась синхронизация.


class MyClass {

    void someMethod() {
        SyncObj syncObj = new SyncObj();
        synchronized (syncObj) {
            try {
                syncObj.notify();
                wait(1000); // IllegalMonitorStateException. wait() вызван на объекте this
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
    }
}
Важно понимать разницу между ссылкой на объект и объектом. Если ссылка стала указывать на другой объект, то попытка вызвать через неё wait(), notify() или notifyAll() приведёт к выбросу IllegalMonitorStateException.


class MySynchronized {

    public static void main(String[] args) {
        MySynchronized ms = new MySynchronized();
        synchronized (ms) {
            ms = new MySynchronized();
            ms.notify(); //IllegalMonitorStateException, лок удерживается не на том объекте, 
                        // на котором вызывается notify()
        }
    }
}
Многопоточность