死鎖及解決方法

死鎖的概念

\quad“死鎖”指的是:
\quad多個線程各自佔有一些共享資源,並且互相等待其他線程佔有的資源才能進行,而導致兩個或者多個線程都在等待對方釋放資源,都停止執行的情形。
\quad因此, 某一個同步塊需要同時擁有“兩個以上對象的鎖”時,就可能會發生“死鎖”的問題。下面案例中,“化妝線程”需要同時擁有“鏡子對象”、“口紅對象”才能運行同步塊。那麼,實際運行時,“玉子的化妝線程”擁有了“鏡子對象”,“千反田的化妝線程”擁有了“口紅對象”,都在互相等待對方釋放資源,才能化妝。這樣,兩個線程就形成了互相等待,無法繼續運行的“死鎖狀態”。

public class DeadLock {
    public static void main(String[] args) {
        Markup g1 = new Markup(1, "玉子");
        Markup g2 = new Markup(0, "千反田");
        g1.start();
        g2.start();
    }
}

class Lipstck {

}

class Mirror {

}

class Markup extends Thread {
    static Lipstck stick = new Lipstck();
    static Mirror mirror = new Mirror();


    int choice;
    String girl;

    public Markup(int choice, String girl) {
        this.choice = choice;
        this.girl = girl;
    }

    @Override
    public void run() {
        //化妝
        markup();
    }
    //相互持有對方的對象鎖-->可能造成死鎖
    private void markup() {
        if(choice == 0) {
            synchronized (stick) {
                System.out.println(this.girl+"獲得口紅");
                //2秒後想擁有鏡子的鎖
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (mirror) {
                    System.out.println(this.girl+"照鏡子");
                }
            }
        }
        else {
            synchronized (mirror) {
                System.out.println(this.girl+"照鏡子");
                //2秒後想擁有鏡子的鎖
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (stick) {
                    System.out.println(this.girl+"獲得口紅");
                }
            }
        }
    }
}

\quad死鎖是由於“同步塊需要同時持有多個對象鎖造成”的,要解決這個問題,思路很簡單,就是:同一個代碼塊,不要同時持有兩個對象鎖。
改一下markup()方法,把鎖中鎖拿到外邊:

private void markup() {
    if(choice == 0) {
        synchronized (stick) {
            System.out.println(this.girl+"獲得口紅");
            //2秒後想擁有鏡子的鎖
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        synchronized (mirror) {
            System.out.println(this.girl+"照鏡子");
        }
    }
    else {
        synchronized (mirror) {
            System.out.println(this.girl+"照鏡子");
            //2秒後想擁有鏡子的鎖
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        synchronized (stick) {
            System.out.println(this.girl+"獲得口紅");
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章