Недопустимое состояние монитора Исключение при ожидании двух шагов
HI написал пример программы для тестирования поведения ожидания в Java.
Моя реализация Runnable:
class ThreadWait implements Runnable {
Object lock = new Object();
ThreadWait(Object lock){
this.lock = lock;
}
@Override
public void run() {
try {
synchronized (lock){
System.out.println("Started : "+Thread.currentThread().getName());
wait();
System.out.println("Completed : "+Thread.currentThread().getName());
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Используется в моем main
лайк:
Object lock = new Object();
ThreadWait t1 = new ThreadWait(lock);
ThreadWait t2 = new ThreadWait(lock);
Thread a= new Thread(t1);
a.setName("A");
Thread b= new Thread(t2);
b.setName("B");
a.start();
b.start();
При запуске этой программы я получаю это исключение:
Exception in thread "A" Exception in thread "B" java.lang.IllegalMonitorStateException
Started : A
at java.lang.Object.wait(Native Method)
Started : B
at java.lang.Object.wait(Object.java:502)
at ThreadWait.run(SynchronizedExample.java:34)
at java.lang.Thread.run(Thread.java:745)
java.lang.IllegalMonitorStateException
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:502)
at ThreadWait.run(SynchronizedExample.java:34)
at java.lang.Thread.run(Thread.java:745)
1 ответ
Ваша проблема в том, что вы синхронизированы на lock
, но вы ждете this
(в частности: экземпляр Runnable, который содержит ожидание вызова).
Вы можете вызвать ожидание только на объектах, на которых у вас есть монитор. Ваш код принадлежит lock
, но нет this
!
Так что вам стоит подождать на объекте блокировки. Но обратите внимание: тогда ваш код будет тупиковым!
Это приводит к совету: вы должны изучить "теорию" немного больше. Видите ли, можно использовать wait / notify, чтобы "синхронизировать" разные потоки, которые должны работать с одними и теми же данными; но это не то, чему вы учитесь (эффективно) методом проб и ошибок; поскольку существует слишком много тонких деталей, которые влияют на результаты экспериментов методом проб и ошибок. Вы можете начать читать здесь или там.
Последнее слово: также важно понимать, что да, ждать / уведомлять - важные понятия; но вы редко используете их в "реальном мире". Это механизмы очень низкого уровня, и Java добавил к ним более мощные абстракции.