Java一個死鎖的例子
阿新 • • 發佈:2019-01-09
一.死鎖的概念
在計算機系統中同時具備下面四個必要條件時,那麼會發生死鎖。
〈1〉互斥條件。即某個資源在一段時間內只能由一個程序佔有,不能同時被兩個或兩個以上的程序佔有。
〈2〉不可搶佔條件。程序所獲得的資源在未使用完畢之前,資源申請者不能強行地從資源佔有者手中奪取資源,而只能由該資源的佔有者程序自行釋放。
〈3〉佔有且申請條件。程序至少已經佔有一個資源,但又申請新的資源;由於該資源已被另外程序佔有,此時該程序阻塞;但是,它在等待新資源之時,仍繼續佔用已佔有的資源。
〈4〉迴圈等待條件。存在一個程序等待序列{P1,P2,...,Pn},其中P1等待P2所佔有的某一資源,P2等待P3所佔有的某一源,......,而Pn等待P1所佔有的的某一資源,形成一個程序迴圈等待環。
上面我們提到的這四個條件在死鎖時會同時發生。也就是說,只要有一個必要條件不滿足,則死鎖就可以排除。
下面看一個Java死鎖的例子:
在上面的程式中兩個執行緒會產生死鎖,執行緒threadA在持有A物件鎖的同時等待執行緒threadB釋放物件B的鎖,執行緒threadB在持有物件B的鎖的同時在等待執行緒A釋放物件A的鎖,從而兩個執行緒一直等待下去,程式得不到任何輸出,也不會結束。public class DeadLockDemo { private static String A="A"; private static String B="B"; public static void main(String[] args){ new DeadLockDemo().deadLock(); } private void deadLock(){ Thread threadA=new Thread(new Runnable(){ @Override public void run(){ synchronized(A){ try { Thread.currentThread().sleep(2000); //睡兩秒確保了阻塞,不然可能直接執行下去了 } catch (InterruptedException e) { e.printStackTrace(); } synchronized(B){ System.out.println("AB"); } } } }); Thread threadB=new Thread(new Runnable(){ @Override public void run(){ synchronized(B){ try { Thread.currentThread().sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized(A){ System.out.println("BA"); } } } }); threadA.start(); threadB.start(); } }
上面的只是死鎖最簡單的一種例子,而在實際情況中產生的死鎖往往是複雜的,例如:A執行緒等待B執行緒釋放資源,B執行緒等待C執行緒釋放資源,C執行緒等待D執行緒釋放資源,D執行緒等待E執行緒釋放資源,E執行緒等待F執行緒釋放資源,F執行緒又等待A執行緒釋放資源,構成一個迴圈等待鏈,產生複雜的死鎖,解決起來也會很麻煩。