См. Документ wait
, notify
и notifyAll
:
Thorws IllegalMonitorStateException - если текущий поток не является
владелец монитора объекта.
Это означает, что вы не можете вызывать их, пока не получите блокировку монитора, другими словами, пока вы не введете синхронизированный блок или синхронизированный метод (проверьте этот для получения дополнительной информации) .
Еще одна важная вещь: вы должны синхронизироваться на одном и том же объекте.
- Когда вы используете синхронизированный блок с объектом экспликации, вы должны вызывать
wait
и notify
для этого объекта.
- Когда вы используете синхронизированный метод , вы неявно синхронизируетесь с
this
, поэтому вам следует вызывать this.wait()
и this.notify()
(ключевое слово this
не обязательно).
В этом случае вам необходимо создать Object
в качестве блокировки монитора и разделить ее между различными классами.
Соответствующий пример:
synchronized (obj) {
while (<condition does not hold>)
obj.wait();
... // Perform action appropriate to condition
}
synchronized (obj) {
... // Prepare the condition
obj.notifyAll();
}
Несоответствующий пример:
void waitMethod() {
wait(); // throws IllegalMonitorStateException
}
void notifyMethod() {
notify(); // throws IllegalMonitorStateException
}
Несоответствующий пример:
synchronized (obj1) {
while (<condition does not hold>)
obj1.wait();
... // Perform action appropriate to condition
}
synchronized (obj2) {
... // call notifyAll on obj2 will not stop the wait on obj1
obj2.notifyAll();
}
Несоответствующий пример:
in class1
synchronized void waitMethod() {
while(someCondition()) {
wait();
}
}
in class2
synchronized void notifyMethod() {
notify(); // call notifyAll on class2 will not stop the wait on class1
}