死鎖_Java產生死鎖的簡單案例

一、簡介

多個線程各自佔有一些共享資源,並且互相等待其它線程佔有的資源才能進行,而導致的兩個或多個線程都在等待對方釋放資源,都停止執行的情景。某一個同步塊同時擁有“兩個以上對象的鎖”時,就可能會發生“死鎖”的問題。

主要點:

  • 過多的同步可能造成相互不釋放資源。
  • 從而互相等待,一般發生於同步中持有多個對象的鎖。

解決:不要在同一個代碼塊中,同時持有多個對象的鎖。

二、產生和解決死鎖問題

1、定義量

//口紅
class LipStick {
}
//鏡子
class Mirror {
}

2、定義化妝類,調用產生死鎖代碼

//化妝
class Markup extends Thread {
    static LipStick lipStick = new LipStick();
    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();
    }

3、死鎖的產生位置

//    相互持有對方的對象鎖--》可能造成死鎖
private void markup() {
    if (choice == 0) {
        synchronized (lipStick) {//獲得口紅的鎖
            System.out.println(this.girl + "塗口紅");
//              1秒後想擁有鏡子的鎖
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
//              產生死鎖
             synchronized (lipStick){
             System.out.println(this.girl+"塗口紅");
             }
        }
    } else {
        synchronized (mirror) {//獲得鏡子的鎖
            System.out.println(this.girl + "照鏡子");
//              1秒後想擁有口紅的鎖
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
//              產生死鎖
             synchronized (lipStick){
             System.out.println(this.girl+"塗口紅");
             }
        }
    }
}

4、死鎖的解決

將獲取鎖的代碼往外面移動一個,使先完成照鏡子的動作後,進入線程等待(等待獲取口紅的狀態)。

//  解決死鎖問題
synchronized (lipStick) {
    System.out.println(this.girl + "塗口紅");
}

5、調用方法

public static void main(String[] args) {
    Markup g1 = new Markup(1, "張柏芝");
    Markup g2 = new Markup(0, "張柏芝");
    g1.start();
    g2.start();
}

三、完整代碼

public class DeadLock {
    public static void main(String[] args) {
        Markup g1 = new Markup(1, "張柏芝");
        Markup g2 = new Markup(0, "張柏芝");
        g1.start();
        g2.start();
    }
}

//口紅
class LipStick {

}

//鏡子
class Mirror {

}

//化妝
class Markup extends Thread {
    static LipStick lipStick = new LipStick();
    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 (lipStick) {//獲得口紅的鎖
                System.out.println(this.girl + "塗口紅");
//                1秒後想擁有鏡子的鎖
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
//                產生死鎖
                /**
                 synchronized (lipStick){
                 System.out.println(this.girl+"塗口紅");
                 }
                 */
            }
//            解決死鎖問題
            synchronized (lipStick) {
                System.out.println(this.girl + "塗口紅");
            }
        } else {
            synchronized (mirror) {//獲得鏡子的鎖
                System.out.println(this.girl + "照鏡子");
//                1秒後想擁有口紅的鎖
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
//                產生死鎖
                /**
                 synchronized (lipStick){
                 System.out.println(this.girl+"塗口紅");
                 }
                 */
            }
//            解決死鎖問題
            synchronized (lipStick) {
                System.out.println(this.girl + "塗口紅");
            }
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章