1. 程式人生 > 其它 >java執行緒死鎖講解,白雪公主與灰姑娘搶口紅和鏡子的案例

java執行緒死鎖講解,白雪公主與灰姑娘搶口紅和鏡子的案例

技術標籤:需理解# 多執行緒java多執行緒thread併發程式設計

1.死鎖程式碼

//死鎖:多個執行緒互相抱著對方需要的資源,然後形成僵局
public class DeadLock {
    public static void main(String[] args) {
        Makeup girl1 = new Makeup(0,"灰姑娘");
        Makeup girl2 = new Makeup(1,"白雪公主");

        girl1.start();
        girl2.start();
    }
} //口紅 class Lipstick{ } //鏡子 class Mirror{ } class Makeup extends Thread{ //需要的資源只能有一份,用static來保證只有一份 static Lipstick lipstick = new Lipstick(); static Mirror mirror = new Mirror(); int choice;//選擇 String girlName;//使用化妝品的人 public Makeup(int choice, String girlName) { this
.choice = choice; this.girlName = girlName; } @Override public void run(){ try { makeup();//化妝 } catch (InterruptedException e) { e.printStackTrace(); } } private void makeup() throws InterruptedException { if (choice ==
0){ synchronized (lipstick){//獲得口紅的鎖 System.out.println(this.girlName+"獲得口紅的鎖"); Thread.sleep(1000); synchronized (mirror){//一秒鐘後想獲得鏡子 System.out.println(this.girlName+"獲取鏡子的鎖"); } } }else { synchronized (mirror){//獲得鏡子的鎖 System.out.println(this.girlName+"獲得鏡子的鎖"); Thread.sleep(2000); synchronized (lipstick){//兩秒鐘後,想獲得口紅 System.out.println(this.girlName+"獲取口紅的鎖"); } } } } }

關鍵程式碼

  private void makeup() throws InterruptedException {
        if (choice == 0){
            synchronized (lipstick){//獲得口紅的鎖
                System.out.println(this.girlName+"獲得口紅的鎖");
                Thread.sleep(1000);
                synchronized (mirror){//一秒鐘後想獲得鏡子
                    System.out.println(this.girlName+"獲取鏡子的鎖");
                }
            }
        }else {
            synchronized (mirror){//獲得鏡子的鎖
                System.out.println(this.girlName+"獲得鏡子的鎖");
                Thread.sleep(2000);
                synchronized (lipstick){//兩秒鐘後,想獲得口紅
                    System.out.println(this.girlName+"獲取口紅的鎖");
                }
            }
        }
    }

上述程式碼解析,當一個執行緒A鎖住口紅不放,同時想拿鏡子
但是鏡子被執行緒B鎖住,執行緒B要拿到了口紅才會釋放鏡子
那麼執行緒A就會一直等待執行緒B釋放鏡子鎖
但是執行緒B要拿不到口紅鎖就不會釋放鏡子鎖
所以兩個執行緒互相等待,形成死鎖,程式崩潰
執行結果
在這裡插入圖片描述

2.解決後的程式碼

 private void makeup() throws InterruptedException {
        if (choice == 0){
            synchronized (lipstick){//獲得口紅的鎖
                System.out.println(this.girlName+"獲得口紅的鎖");
                Thread.sleep(1000);
            }
            synchronized (mirror){//一秒鐘後想獲得鏡子
                System.out.println(this.girlName+"獲取鏡子的鎖");
            }
        }else {
            synchronized (mirror){//獲得鏡子的鎖
                System.out.println(this.girlName+"獲得鏡子的鎖");
                Thread.sleep(2000);
            }
            synchronized (lipstick){//兩秒鐘後,想獲得口紅
                System.out.println(this.girlName+"獲取口紅的鎖");
            }
        }
    }

執行緒A拿到了口紅鎖,然後釋放了口紅鎖,想拿鏡子鎖
執行緒B拿到了鏡子鎖,然後釋放了鏡子鎖,再拿口紅鎖
雙方達成共識,不會永久的等待

執行結果
在這裡插入圖片描述