
Методы 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()
}
}
}