2015-11-19 85 views
1

在多線程中工作時,Java中的同步塊是一個很好的功能,這是很常見的。我最瞭解他們的工作方式,但希望在等待和通知(全部)結合時更加確定他們的工作方式。同步塊後面

通常,當一個線程進入一個同步塊時,除非第一個線程已經離開,否則其他線程不能進入該塊。但是,在調用同步對象的等待時,情況並非如此。如果是這樣,另一個線程將無法調用notify(All),這需要在調用對象之前與對象同步。

那麼等待的呼叫是否會使呼叫脫離同步?或者,如果Java在不同的塊中發現通知(全部),它只會發出異常?另外,當從一個同步塊調用等待,然後通知另一個(全部)時,是否有一個線程在繼續之前等待另一個線程完成,如果是,哪一個?

現在我可以設置一個快速測試來回答大部分這個問題,我知道。但它不會回答更技術性的東西,我相信這裏有人可以。我不只是對什麼和什麼時候感興趣,而且也是爲什麼。嘗試搜索一些記錄的信息,但找不到有關wait/notify(All)的任何有用信息。

編輯:

如果其他人應該是有興趣,這是測試結果。如果我們有第一個等待釋放的Thread1,Thread2和Thread3,第三個釋放它們,那麼順序就是這樣。

  1. 線程1進入和調用wait()
  2. 線程2進入和調用wait()
  3. Thread3進入,並調用notifyAll的()
  4. Thread3結束,始終
  5. 等待的線程但是還沒有具體的訂購。首先執行哪一個是完全隨機的,並且與它們的wait()順序無關。但是,調用notify(All)的線程將始終在任何等待線程繼續之前完成。
+0

等待守護程序線程不想執行,直到另一個線程將它們踢掉 –

+1

等待任何線程需要出於任何原因等待另一個線程。問題不在於等待什麼,而在於技術上的工作方式。 Java如何處理它們。 –

+0

_是否等待呼叫,使呼叫脫離同步?_是。線程在'wait()'調用中釋放鎖,然後在wait()返回之前重新獲得鎖。 –

回答

0

是的,它有點特別。 wait釋放在synchronized block中獲取的lock,並暫停它的thread(獲取鎖的線程),這意味着其他線程將被允許獲取鎖並修改狀態。 現在通知或notifyAll將喚醒睡着的線程並且它們重新獲得lock

+0

好吧,如果等待線程在等待釋放時重新獲得鎖,那麼線程調用notify(All)將已經鎖定同步對象,因爲notify(All)需要位於同步塊。這意味着調用notify(All)的線程將在等待的線程繼續之前完成? –

+0

@DanielB記住了一些事情,它在關鍵部分是一次一個線程。notifyAll將從文檔中重新獲取它已放棄的鎖定:「喚醒的線程將無法繼續,直到當前線程放棄對該對象的鎖定爲止」 –

+0

謝謝,這有助於。但是最好設置一個小測試來確保我知道執行所有事情的確切順序。 –