2014-04-11 116 views
0

如果其他線程等待不同的條件,我們應該調用notifyAll(),這樣每個其他線程都有機會獲得執行。但是我們犯了一個錯誤,我們假設所有線程都在等待相同的條件,我們調用notify(),讓JVM選擇一個線程,但是選中的線程不能運行,因爲條件仍然不能滿足,那麼會發生什麼?當我們使用錯誤的notify()時會發生什麼?

所有線程都停止運行?或者JVM繼續選擇另一個線程來喚醒,就像notifyALL()一樣?

+1

'但選中的線程無法運行,因爲條件仍然不能滿足請詳細說明? –

+0

線程a:while(a> 0),線程b:while(b> 0),線程c:while(c> 0)... – lovespring

+0

'notify'喚醒已在該對象上調用wait的線程。這裏沒有什麼可以滿足的。 –

回答

1

JVM不能繼續選擇另一個線程來喚醒,因爲重新輸入wait的決定發生在更高級別的邏輯上,超出了線程調度程序的「時域」範圍。所以是的,在你描述的場景中,所有的線程都會繼續等待。

0

在這種情況下,您應該有一個deadlock,因爲所有的線程都會停滯不前。

0
thread a: while(a>0), thread b: while(b>0), thread c: while(c>0) 

這是您的代碼邏輯有缺陷。是的,這將導致deadlock。既然你有線程將繼續吃掉你的CPU,並且因爲它擁有鎖定,所以其他線程無法獲取它。

所有線程都停止運行?或者JVM繼續選擇另一個線程來喚醒,就像notifyALL()一樣?

將獲得關鍵區域鎖定的線程將進入無限循環。所有其他線程將繼續等待。只要某個線程持有該鎖,任何JVM都不會通知其他線程。

0

所有等待同一監視器的線程都應等待循環中的相同條件成爲true。通知()顯示器的線程只能在使條件成立之後這樣做。如果你遵循這些規則,那麼至少有一個線程會醒來並能夠取得進展。

E.g .;

final Object lock = new Object(); 
final AtomicBoolean timeToGo = new AtomicBoolean(false); 

Runnable waiter = new Runnable() { 
    public void run() { 
     synchronized(lock) { 
      while (! timeToGo.get()) { 
       lock.wait(); 
      } 
      System.out.println("Hello!"); 
      timeToGo.set(false); 
     } 
    } 
}; 

Runnable notifier = new Runnable() { 
    public void run() { 
     synchronized(lock) { 
      timeToGo.set(true); 
      lock.notify(); 
     } 
    } 
}; 

如果五個線程都掛在waiter.run()的wait()的方法,並且一個線程調用notifier.run(),然後正好五個一會打印「Hello!」並退出。其他人將繼續等待下一個notifier.run()調用。當調用notifier.run()時,如果想讓所有線程都打印hello,則將lock.notify()調用更改爲lock.notifyAll(),並從waiter.run()中刪除該行,即將標誌設置爲false。

相關問題