java多線程系列-----死鎖以及解決死鎖的辦法

死鎖的四個必要條件

1)互斥條件,即某個資源在一段時間內只能由一個線程佔有,不能同時被兩個或兩個以上的線程佔有

2)不可搶佔條件,線程所獲得的資源在未使用完畢之前,資源申請者不能強行地從資源佔有者手中奪取資源,而只能由該資源的佔有者線程自行釋放

3)佔有且申請條件,線程至少已經佔有一個資源,但又申請新的資源;由於該資源已被另外線程佔有,此時該線程阻塞;但是,它在等待新資源之時,仍繼續佔用已佔有的資源。

4)循環等待條件,存在一個線程等待序列{P1,P2,...,Pn},其中P1等待P2所佔有的某一資源,P2等待P3所佔有的某一源,......,而Pn等待P1所佔有的的某一資源,形成一個線程循環等待環

 

解決死鎖的辦法:

1. 加鎖順序

儘量不要使用嵌套鎖,注意順序,不要同一時間多個線程搶佔同一資源對象

2. 死鎖檢測

允許系統進入死鎖狀態,然後檢測它,並加以恢復

死鎖的檢測

(該部分講述如何判斷是否產生死鎖)

1、畫出資源分配圖

系統死鎖,可利用資源分配圖來描述。如下圖所示,用長方形代表一個進程,用框代表一類資源。由於一種類型的資源可能有多個,用框中的一個點代表一類資源中的一個資源。從進程到資源的有向邊叫請求邊,表示該進程申請一個單位的該類資源;從資源到進程的邊叫分配邊,表示該類資源已經有一個資源被分配給了該進程。

 

 

2、簡化資源分配圖

第一步:先看A資源,它有三個箭頭是向外的,因此它一共給進程分配了3個資源,此時,A沒有空閒的資源剩餘。

第二步:再看B資源,它有一個箭頭是向外的,因此它一共給進程分配了1個資源,此時,B還剩餘一個空閒的資源沒分配。 

第三步:看完資源,再來看進程,先看進程P2,它只申請一個A資源,但此時A資源已經用光了,所以,進程P2進入阻塞狀態,因此,進程P2暫時不能化成孤立的點。 

第四步:再看進程P1,它只申請一個B資源,此時,系統還剩餘一個B資源沒分配,因此,可以滿足P1的申請。這樣,進程P1便得到了它的全部所需資源,所以它不會進入阻塞狀態,可以一直運行,等它運行完後,我們再把它的所有的資源釋放。相當於:可以把P1的所有的邊去掉,變成一個孤立的點,如下圖所示:

 

第五步:進程P1運行完後,釋放其所佔有的資源(2個A資源和1個B資源),系統回收這些資源後,空閒的資源便變成2個A資源和1個B資源,由於進程P2一直在申請一個A資源,所以此時,系統能滿足它的申請。這樣,進程P2便得到了它的全部所需資源,所以它不會進入阻塞狀態,可以一直運行,等它運行完後,我們再把它的所有的資源釋放。相當於:可以把P2的所有的邊都去掉,化成一個孤立的點,變成下圖: 

(若能消去圖中所有的邊,則稱該圖是可完全簡化的,如上圖)

3、使用死鎖定理判斷

死鎖定理: 
                     ①如果資源分配圖中沒有環路,則系統沒有死鎖; 
                     ②如果資源分配圖中出現了環路,則系統可能有死鎖。 
或者說: 
當且僅當S狀態的資源分配圖是不可完全簡化的時候,系統狀態則是死鎖狀態

 

死鎖的解除

1、資源剝奪法

掛起某些死鎖進程,並搶佔它的資源,將這些資源分配給其他的死鎖進程。但應防止被掛起的進程長時間得不到資源,而處於資源匱乏的狀態。

2、撤銷進程法

強制撤銷部分、甚至全部死鎖進程並剝奪這些進程的資源。撤銷的原則可以按進程優先級和撤銷進程代價的高低進行。

3、進程回退法

讓一(多)個進程回退到足以迴避死鎖的地步,進程回退時自願釋放資源而不是被剝奪。要求系統保持進程的歷史信息,設置還原點。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章