2013-07-07 1 views
1
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, я освобождаю блокировку.IllegalMonitorStateException в коде

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

+0

Ум, здесь нет нитей, кроме основного, если у меня что-то не хватает. Пожалуйста, разместите свою полную стек. – hexafraction

+0

Какая строка выдает исключение? – zch

+4

Вы держите монитор для объекта args, но вызываете 'wait()' для текущего объекта потока. Вам нужно вызвать 'wait()' на объект, на который вы держите монитор. См. этот вопрос: http://stackoverflow.com/questions/3773807/threads-synchronizing-in-java-illegalmonitorstateexception?rq=1 – confusopoly

ответ

4

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

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

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

+0

спасибо JB. это была моя тестовая программа, чтобы понять функциональность ожидания. Я получил объяснение. –

3

От IllegalMonitorStateExceptiondocumentation

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

От Object#notify()documentation

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

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

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

synchronized (args) { 
    //... 
} 

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

0

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

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

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

+0

yaah Я знал, что в программе нет нитей, кроме основного потока, просто пыталась завладеть обычной концепцией потоковой передачи. bdw благодарит меня за помощь –

Смежные вопросы