[英]Does Thread.join() release the lock? Or continue to hold it?
據我了解,內部obj.join()
調用wait()
。 這意味着join()
總是釋放鎖(因為wait()
總是在被調用后釋放鎖)。
API文檔說明 :
此實現使用的循環
this.wait
電話空調上this.isAlive
。 當線程終止時,將調用this.notifyAll
方法。 建議應用程序不要在Thread
實例上使用wait
,notify
或notifyAll
。
有人在這里說join()
不會釋放任何鎖,因為API沒有明確提及它。 但是這種邏輯對我來說似乎很奇怪。
這是join()
代碼的主要邏輯:
while (isAlive()) {
wait(0);
}
該站點進一步加劇了混亂(我認為它們是錯誤的):
3)的第三個區別
wait()
和join()
的方法是,當一個線程調用wait()
方法,它釋放了在該對象持有的任何鎖wait()
被調用,但調用join()
方法沒有按不要釋放任何監視器或鎖。
wait
釋放保留在調用了wait
的對象上的監視器,但不釋放任何其他監視器。
當前線程必須擁有該對象的監視器。 線程釋放該監視器的所有權並等待。
換句話說,給出以下內容:
synchronized (a) {
synchronized (b) {
b.wait();
}
}
在b.wait()
當前線程釋放b
的顯示器,而不是a
的顯示器。
如果t.join()
使用實施t.wait()
內部,然后t
的監視器被釋放,同時等待,但不排除任何其它的顯示器。
順便說一句,這種join
實現是泄漏抽象的情況。 如果Thread
使用了private final Object monitor;
要等待,我們可以說join
沒有釋放任何監視器,即使join
內部在我們不知情的情況下使用wait
。 沒有理由記錄使用wait
的實現細節,因為我們無法訪問監視器,因此我們無需了解它。
我們知道join
內部使用wait
的原因是,最初編寫該方法的人選擇了我們可以訪問的監視器。 這就需要揭示實施細節。 從我們的角度來看, join
並不是真的應該釋放監視器,而只是等待線程完成,但是選擇了一個實現,這需要我們比我們應該了解的更多。
盡管@Radiodef的出色答案闡明並闡述了抽象泄漏的缺點,但以更簡單的方式回答@vrinchvucz的困惑,答案是,
是的,當線程調用t.join
它確實獲取並釋放了“ a”監視器鎖定。 該監視器鎖是線程t
本身的監視器鎖,因為Thread類上join方法的實現是通過在synchronized
join
方法內部使用this.wait
實現的,這是@Radiodef指向的泄漏抽象問題。
因此,除非線程在調用t.join
之前獲取了t
本身的監視器鎖, t.join
我們可以說在t.join
調用中不會釋放任何客戶機/用戶獲得的監視器鎖(因為所討論的監視器鎖與客戶機/在調用t.join
的線程中獲取的用戶代碼。
這是因為正如Object#wait的文檔中明確指出的那樣
請注意,wait方法將當前線程放入該對象的等待集中,因此只會解鎖該對象; 當線程等待時,當前線程可以在其上同步的所有其他對象保持鎖定。
這就是為什么Thread#join
的文檔沒有提及有關釋放鎖的任何內容,同時仍提供了有關this.wait
的使用的實現細節。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.