簡體   English   中英

Thread.join()是否釋放鎖? 還是繼續持有它?

[英]Does Thread.join() release the lock? Or continue to hold it?

據我了解,內部obj.join()調用wait() 這意味着join()總是釋放鎖(因為wait()總是在被調用后釋放鎖)。

API文檔說明

此實現使用的循環this.wait電話空調上this.isAlive 當線程終止時,將調用this.notifyAll方法。 建議應用程序不要在Thread實例上使用waitnotifynotifyAll

有人在這里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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM