死鎖的例子以及解決辦法

給個死鎖的例子:

public class TestDeadLock implements Runnable{
    public int flag = 0;
    static Object o1 = new Object();
    static Object o2 = new Object();
    @Override
    public void run() {
        if(flag == 0){
            synchronized (o1){
                System.out.println("flag=0獲取Object1的鎖");
                try{
                    Thread.sleep(1000);
                }catch (InterruptedException e){
                    e.printStackTrace();
                }
                synchronized (o2){
                    System.out.println("flag=0獲取Object2的鎖");
                }
            }
        }
        if(flag == 1){
            synchronized (o2){
                System.out.println("flag=1獲取Object2的鎖");
                try{
                    Thread.sleep(1000);
                }catch (InterruptedException e){
                    e.printStackTrace();
                }
                synchronized (o1){
                    System.out.println("flag=1獲取Object1的鎖");
                }
            }
        }
    }
    public static void main(String[] args) {
        TestDeadLock td1 = new TestDeadLock();
        TestDeadLock td2 = new TestDeadLock();
        td1.flag = 0;
        td2.flag = 1;
        new Thread(td1).start();
        new Thread(td2).start();
    }
}

Object1和Object2定爲static,保證實例只有一份:

輸出結果:(產生死鎖)

flag=0獲取Object1的鎖
flag=1獲取Object2的鎖
。。。。。(程序發生死鎖)

上訴代碼經過以下修改可以避免死鎖的發生:

public class TestDeadLock implements Runnable{
    public int flag = 0;
    static Object o1 = new Object();
    static Object o2 = new Object();
    @Override
    public void run() {
        if(flag == 0){
            synchronized (o1){
                System.out.println("flag=0獲取Object1的鎖");
                try{
                    Thread.sleep(1000);
                }catch (InterruptedException e){
                    e.printStackTrace();
                }
            }
            synchronized (o2){
                System.out.println("flag=0獲取Object2的鎖");
            }
        }
        if(flag == 1){
            synchronized (o2){
                System.out.println("flag=1獲取Object2的鎖");
                try{
                    Thread.sleep(1000);
                }catch (InterruptedException e){
                    e.printStackTrace();
                }
            }
            synchronized (o1){
                System.out.println("flag=1獲取Object1的鎖");
            }
        }
    }
    public static void main(String[] args) {
        TestDeadLock td1 = new TestDeadLock();
        TestDeadLock td2 = new TestDeadLock();
        td1.flag = 0;
        td2.flag = 1;
        new Thread(td1).start();
        new Thread(td2).start();
    }
}
輸出結果:

flag=0獲取Object1的鎖
flag=1獲取Object2的鎖
flag=1獲取Object1的鎖
flag=0獲取Object2的鎖

避免死鎖的方法:

(1)上述demo最常見,在佔有一個資源的時候繼續申請佔有另外一個資源,這種情況下在其他線程試圖申請前一個線程佔有的資源時容易發生死鎖。避免嵌套申請鎖

(2)還有一些方法:

  • 加鎖順序(線程按照一定的順序加鎖)
  • 加鎖時限(線程嘗試獲取鎖的時候加上一定的時限,超過時限則放棄對該鎖的請求,並釋放自己佔有的鎖)
  • 死鎖檢測

參考博客:http://blog.csdn.net/ls5718/article/details/51896159


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