1. 程式人生 > >Java一個死鎖的例子

Java一個死鎖的例子

一.死鎖的概念

在計算機系統中同時具備下面四個必要條件時,那麼會發生死鎖。

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

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

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

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

  上面我們提到的這四個條件在死鎖時會同時發生。也就是說,只要有一個必要條件不滿足,則死鎖就可以排除。

下面看一個Java死鎖的例子:

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();  
    }  
} 
在上面的程式中兩個執行緒會產生死鎖,執行緒threadA在持有A物件鎖的同時等待執行緒threadB釋放物件B的鎖,執行緒threadB在持有物件B的鎖的同時在等待執行緒A釋放物件A的鎖,從而兩個執行緒一直等待下去,程式得不到任何輸出,也不會結束。
上面的只是死鎖最簡單的一種例子,而在實際情況中產生的死鎖往往是複雜的,例如:A執行緒等待B執行緒釋放資源,B執行緒等待C執行緒釋放資源,C執行緒等待D執行緒釋放資源,D執行緒等待E執行緒釋放資源,E執行緒等待F執行緒釋放資源,F執行緒又等待A執行緒釋放資源,構成一個迴圈等待鏈,產生複雜的死鎖,解決起來也會很麻煩。