2011-05-19 61 views
3

我有對象線程A正在調用wait()同時線程B另一個對象然後做一些工作要求線程A的對象的notify()。線程A然後執行一些後處理。Java的等待()不拋出InterruptedException的

我的問題很簡單:在「不再等待」而不是INFO消息

synchronized(this) 
{ 
    while(!flag) 
    { 
     try 
     { 
      wait(); 
      getLogger().info("No longer waiting"); 
     } 
     catch (InterruptedException ie) 
     { 
      getLogger().info("Wait threw InterruptedException"); 
     } 
    } 
} 

結果「等等義無返顧InterruptedException的」。

我很困惑,因爲這個(http://download.oracle.com/javase/1.5.0/docs/api/java/lang/Object.html#wait()):

拋出:

InterruptedException的 - 如果另一個線程之前或在當前線程在等待中斷的 當前線程一個 通知。拋出此異常時,當前線程的中斷狀態將被清除 。

爲什麼我會得到奇怪的行爲?

謝謝。

+0

調用對象的另一個線程「notify」不符合中斷的要求。 – sje397 2011-05-19 06:18:02

回答

9

當一個線程使用wait()等待時,他實際上等待notify()。所以一旦notify()已被其他線程調用,此線程將繼續,如果您打電話給interrupt(),您將得到異常。

此外,從文件鏈接到您:

導致當前線程等待,直到 其他線程調用通知() 方法或 的notifyAll的()方法,該對象

notify從鎖釋放線程。

InterruptedException - 如果另一個線程 之前或同時中斷了當前線程 當前線程 等待通知。

 

+0

謝謝,我假設notify()導致wait()拋出一個InterruptedException。 – 2011-05-19 06:39:36

+0

@Liam - 第1課 - 讀取一個方法的javadoc的*全部*。不要「假設」... – 2011-05-19 06:44:13

2

notify()對於wait() -ing的線程不是異常的指示。例如,如果線程在調用notify()之前被終止,則不會調用notify()。線程沒有中斷 - 它已被喚醒。

3

notify()不會使wait()拋出InterruptedExceptionnotify()wait()繼續正常的程序流程。

0

注意,您必須在代碼中的錯誤。等待應該始終在循環中調用,並在喚醒後檢查條件。可以通過虛假喚醒喚醒等待。請參閱javadoc wait()

+0

鑑於我們沒有看到任何代碼的上下文,你不能說它有一個錯誤。它也不在同步模塊中,但我假設有一個地方。 – 2011-05-19 06:23:18

+0

是的,對不起,我編輯了它。 謝謝澄清! – 2011-05-19 06:33:58

+0

@Jon Skeet。原始帖子沒有一個條件循環,並且OP說「線程A然後執行一些後處理。」意味着他想等待另一個線程完成處理。由於虛假的喚醒,等待沒有條件檢查是一個錯誤。線程可以在沒有通知的情況下喚醒,然後在另一個線程完成之前開始後處理。 – Kaj 2011-05-19 06:56:24