IllegalMonitorStateException в коде

class Test {

    public static void main(String[] args) {

        System.out.println("1.. ");
        synchronized (args) {

            System.out.println("2..");

            try {
                Thread.currentThread().wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            System.out.println("3..");
        }

    }
}

я получаю IllegalMonitorStateException отслеживать исключение в этом коде. Насколько я понимаю, из-за синхронизированного блока вокруг args который является объектом массива строк, текущий поток должен получить блокировку, и с помощью метода wait я снимаю блокировку.

Может кто-нибудь объяснить мне причину этого исключения?

3 ответа

Ты звонишь wait() на Thread.currentThread(), Перед звонком wait() для любого объекта вы должны владеть монитором этого объекта путем синхронизации синхронизированного блока с этим объектом. Итак, чего не хватает, так это

synchronized(Thread.currentThread()) {
    Thread.currentThread().wait();
}

Это сказал, позвонив wait() на объекте Thread это не то, что вы должны делать, и, вероятно, показывает, что вы не поняли, что wait() делает, особенно если учесть, что у вас нет другого вызывающего потока notify() или же notifyAll(), Синхронизация аргументов, передаваемых методу main, также является очень странным выбором. wait() это очень низкоуровневый метод, который следует использовать редко, даже если вы полностью понимаете, что он делает. Для лучшего ответа вы должны объяснить, что вы на самом деле хотите, чтобы этот код делал.

От IllegalMonitorStateException документация

Брошенный, чтобы указать, что поток попытался ждать на мониторе объекта или уведомить другие потоки, ожидающие на мониторе объекта, не имея указанного монитора

От Object#notify() документация

Поток становится владельцем монитора объекта одним из трех способов:

  • Выполняя синхронизированный метод экземпляра этого объекта.
  • Выполняя тело синхронизированного оператора, который синхронизируется на объекте.
  • Для объектов типа Class, выполняя синхронизированный статический метод этого класса.

Так как поток выполняет блок синхронизирован на args объект

synchronized (args) {
    //...
}

ты должен позвонить args.wait() вместо Thread.currentThread().wait();,

Привет, Ankit. Я предполагаю, что ты пытаешься изучить некоторые основные понятия многопоточности. попробуйте получить некоторые хорошие онлайн-учебники: http://www.javaworld.com/jw-04-1996/jw-04-threads.html

или попробуйте какую-нибудь простую хорошую книгу. http://www.amazon.com/SCJP-Certified-Programmer-Java-310-065/dp/0071591060/

Программа, которую вы написали, на самом деле не нуждается в синхронизации, так как существует только один поток (основной). Я знаю, что вы просто пробуете свои силы, поэтому даете некоторое представление. Даже если вы правильно вызвали метод ожидания для args(args.wait()) или синхронизировали в Thread.currentThread, ваш поток может переместиться на неопределенное время ожидания (что делает вашу программу не отвечающей), потому что нет другого потока, который бы уведомил ваш основной поток.

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