如果其他線程等待不同的條件,我們應該調用notifyAll(),這樣每個其他線程都有機會獲得執行。但是我們犯了一個錯誤,我們假設所有線程都在等待相同的條件,我們調用notify(),讓JVM選擇一個線程,但是選中的線程不能運行,因爲條件仍然不能滿足,那麼會發生什麼?當我們使用錯誤的notify()時會發生什麼?
所有線程都停止運行?或者JVM繼續選擇另一個線程來喚醒,就像notifyALL()一樣?
如果其他線程等待不同的條件,我們應該調用notifyAll(),這樣每個其他線程都有機會獲得執行。但是我們犯了一個錯誤,我們假設所有線程都在等待相同的條件,我們調用notify(),讓JVM選擇一個線程,但是選中的線程不能運行,因爲條件仍然不能滿足,那麼會發生什麼?當我們使用錯誤的notify()時會發生什麼?
所有線程都停止運行?或者JVM繼續選擇另一個線程來喚醒,就像notifyALL()一樣?
JVM不能繼續選擇另一個線程來喚醒,因爲重新輸入wait
的決定發生在更高級別的邏輯上,超出了線程調度程序的「時域」範圍。所以是的,在你描述的場景中,所有的線程都會繼續等待。
在這種情況下,您應該有一個deadlock
,因爲所有的線程都會停滯不前。
thread a: while(a>0), thread b: while(b>0), thread c: while(c>0)
這是您的代碼邏輯有缺陷。是的,這將導致deadlock
。既然你有線程將繼續吃掉你的CPU,並且因爲它擁有鎖定,所以其他線程無法獲取它。
所有線程都停止運行?或者JVM繼續選擇另一個線程來喚醒,就像notifyALL()一樣?
將獲得關鍵區域鎖定的線程將進入無限循環。所有其他線程將繼續等待。只要某個線程持有該鎖,任何JVM都不會通知其他線程。
所有等待同一監視器的線程都應等待循環中的相同條件成爲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。
'但選中的線程無法運行,因爲條件仍然不能滿足請詳細說明? –
線程a:while(a> 0),線程b:while(b> 0),線程c:while(c> 0)... – lovespring
'notify'喚醒已在該對象上調用wait的線程。這裏沒有什麼可以滿足的。 –