2017-04-25 84 views

回答

1

有兩種流行的方法來檢測死鎖。

一個是讓線程設置檢查點。例如,如果您有一個擁有工作循環的線程,則可以在開始工作時設置一個計時器,該計時器的設置時間長於您認爲工作可能需要的時間。如果計時器觸發,則認爲線程已死鎖。工作完成後,您取消定時器。

另一個(有時候組合使用)是讓一個線程可能會阻塞線程可能保存的其他資源。當其他線程以相反的順序獲取這些鎖時,這可以直接檢測到獲取一個鎖的嘗試,同時持有另一個鎖。

這甚至可以檢測死鎖的風險,而不會實際發生死鎖。如果一個線程獲取了鎖A然後B並且另一個線程獲得了鎖B然後A,那麼除非它們重疊,否則沒有死鎖。但是這種方法可以檢測到它。

高級死鎖檢測通常僅用於調試過程中。除了編寫應用程序來檢查每個阻塞鎖是否存在可能的死鎖並知道如果發生該怎麼辦,在死鎖之後您唯一可以做的事情是將應用程序關閉。您不能盲目釋放鎖,因爲它們保護的資源可能處於不一致的狀態。

有時候你會故意寫出你知道會死鎖的代碼,並專門編碼以避免這個問題。例如,如果知道很多線程需要鎖A,然後嘗試獲取鎖B,並且其他一些線程需要做相反的處理,那麼可以編寫它,執行非阻塞嘗試來鎖定B,如果失敗,則釋放鎖A 。

通常,花費你的努力使死鎖變得不可能,而不是讓代碼檢測和解決死鎖是更有用的。

+0

是否可以使用java線程轉儲來檢測死鎖?它可以告訴被阻塞的線程,但不知道是否可以檢測到死鎖。 –

+0

@AmberBeriwal這可以工作。隨着所有線程堆棧的轉儲,您可以嘗試確定哪個線程阻塞嘗試獲取鎖,以及哪個線程持有該鎖。如果你有很多線程,但是並非不可能,那很乏味。 –