2013-07-07 36 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是字符串數組對象的同步塊,當前線程必須已經獲得了鎖並且使用等待方法,我釋放了鎖。IllegalMonitorStateException代碼

有人能解釋一下這個例外背後的原因嗎?

+0

嗯,除了主要的東西之外,沒有線程在這裏創建,除非我失去了一些東西。請發佈您的完整堆棧跟蹤。 – hexafraction

+0

哪一行引發異常? – zch

+4

您正在爲args對象持有監視器,但在當前線程對象上調用wait()。你需要在你正在監視的對象上調用'wait()'。見例如這個問題:http://stackoverflow.com/questions/3773807/threads-synchronizing-in-java-illegalmonitorstateexception?rq=1 – confusopoly

回答

4

您在Thread.currentThread()上致電wait()。在任何對象上調用wait()之前,您必須擁有該對象的監視器,通過對該對象上的同步塊同步的方式。那麼,什麼是缺少的是

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

這就是說,一個線程調用對象的wait()是不是你應該做的,而且很可能表明你沒有理解什麼wait()呢,尤其是考慮到你沒有任何其他線程調用notify()notifyAll()。同步傳遞給主方法的參數也是一個非常奇怪的選擇。 wait()是一種非常低級的方法,即使您完全理解它的功能,也應該很少使用它。爲了得到更好的答案,你應該解釋你實際上想要這個代碼做什麼。

+0

謝謝JB。這是我的測試程序,瞭解等待的功能。我得到了解釋。 –

3

IllegalMonitorStateExceptiondocumentation

拋出的異常表明某一線程已經試圖等待對象的監視器,或者不擁有指定的監控

通知其他線程正在等待對象的監視器上來自Object#notify()documentation

甲線程成爲對象監視器的在三種方式之一的所有者:

  • 通過執行對象的同步實例方法。
  • 通過執行在對象上同步的同步語句的主體。
  • 對於Class類型的對象,通過執行該類的同步靜態方法。

如此以來,線程執行塊args對象

synchronized (args) { 
    //... 
} 

同步你應該叫args.wait()代替Thread.currentThread().wait();

0

嗨ankit我假設你正試圖學習一些基本的多線程概念。 試圖找到一些很好的在線教程:http://www.javaworld.com/jw-04-1996/jw-04-threads.html

或嘗試一些基本的好書。http://www.amazon.com/SCJP-Certified-Programmer-Java-310-065/dp/0071591060/

由於只有一個線程(main),因此您編寫的程序實際上不需要同步。我知道你只是在嘗試你的手,因此提供了一些見解。即使您正確調用了args(args.wait())上的等待方法,或者在Thread.currentThread上同步了您的線程,您的線程也可能進入無限期等待狀態(使您的程序無響應),因爲沒有其他線程可以通知您的主線程。

+0

yaah我知道除了程序中的主線程以外沒有其他線程,只是試圖抓住正常的線程概念。 bdw感謝您幫助我 –

相關問題