Недопустимое состояние монитора Исключение при ожидании двух шагов

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 добавил к ним более мощные абстракции.

Другие вопросы по тегам