中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

通俗易懂的Java死鎖代碼示例

發布時間:2020-11-03 16:37:12 來源:億速云 閱讀:143 作者:Leah 欄目:開發技術

今天就跟大家聊聊有關通俗易懂的Java死鎖代碼示例,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。

演示死鎖

package com.yang.kuangTeacher;

import java.util.concurrent.TimeUnit;

/**
 * @author: fudy
 * @date: 2020/9/13 下午 12:21
 * @Decription: 演示死鎖(內容參考B站狂神說JAVA)
 **/
public class DeadLock {

  public static void main(String[] args) {
    MarkUp markUp0 = new MarkUp("迪麗熱巴",0);
    MarkUp markUp1 = new MarkUp("楊冪",1);
    markUp0.start();
    markUp1.start();
  }
}

// 口紅類
class LipStick {
}

// 鏡子類
class Mirror {
}

// 化妝類
class MarkUp extends Thread {

  private int choice;
  private String userName;

  private static LipStick lipStick = new LipStick();
  private static Mirror mirror = new Mirror();

  MarkUp(String userName, int choice) {
    this.userName = userName;
    this.choice = choice;
  }

  @Override
  public void run() {
    try {
      markUP();
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }

  private void markUP() throws InterruptedException {
    // 如果選擇0方式化妝
    if (choice == 0) {
      // 同步代碼塊的鎖,在同步代碼塊有效
      synchronized (lipStick) {
        System.out.println(userName + "拿到了口紅");
        // 拿到口紅后再拿鏡子
        TimeUnit.SECONDS.sleep(1);
        // 程序執行此處會停止 		 -----------------這里死鎖----------------------->
        synchronized (mirror) {
          System.out.println(userName + "拿到了鏡子");
        }
      }
    }
    // 如果選擇1方式化妝
    if (choice == 1) {
      // 同步代碼塊的鎖,在同步代碼塊有效
      synchronized (mirror) {
        System.out.println(userName + "拿到了鏡子");
        // 拿到鏡子后再拿口紅
        TimeUnit.SECONDS.sleep(1);
        // 程序執行此處會停止     -----------------這里死鎖----------------------->
        synchronized (lipStick) {
          System.out.println(userName + "拿到了口紅");
        }
      }
    }
  }
}

我們剛才認為,死鎖是由于同步代碼塊沒有執行完,導致不會釋放鎖,我們分析以上兩個死鎖的原因。

  • 在線程1方式0化妝中由于我們拿到了口紅鎖后,睡眠一秒鐘(有可能先執行線程2)
  • 在線程2方式1化妝中由于我們拿到了鏡子鎖后,睡眠一秒鐘

假如線程1先獲得口紅鎖執行完畢,準備拿鏡子鎖時,發現鏡子對象被持有了,所以他會等待鏡子鎖被釋放。

線程2先執行獲得鏡子鎖完畢,準備拿口紅鎖時,發現口紅對象被持有了,所以他會等待口紅鎖被釋放。

如果我們不關閉程序,兩個線程會一直等待下去。我們可以理解為死鎖,無法釋放鎖。

解決死鎖

在上述例子中,我們因為想同時拿到兩個鎖去做一件事情才會導致死鎖,按照Java Effective提倡減小鎖的范圍,我們對問題進行改進。

我們可以拿到口紅鎖后執行口紅方法后釋放口紅鎖,想要鏡子鎖再同步代碼塊拿鏡子鎖即可。

package com.yang.kuangTeacher;

import java.util.concurrent.TimeUnit;

/**
 * @author: fudy
 * @date: 2020/9/13 下午 12:21
 * @Decription: 演示死鎖(內容參考B站狂神說JAVA)
 **/
public class DeadLock {

  public static void main(String[] args) {
    MarkUp markUp0 = new MarkUp("迪麗熱巴",0);
    MarkUp markUp1 = new MarkUp("楊冪",1);
    markUp0.start();
    markUp1.start();
  }
}

// 口紅類
class LipStick {
}

// 鏡子類
class Mirror {
}

// 化妝類
class MarkUp extends Thread {

  private int choice;
  private String userName;

  private static LipStick lipStick = new LipStick();
  private static Mirror mirror = new Mirror();

  MarkUp(String userName, int choice) {
    this.userName = userName;
    this.choice = choice;
  }

  @Override
  public void run() {
    try {
      markUP();
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }

  private void markUP() throws InterruptedException {
    // 如果選擇0方式化妝
    if (choice == 0) {
      // 同步代碼塊的鎖,在同步代碼塊有效
      synchronized (lipStick) {
        System.out.println(userName + "拿到了口紅");
        TimeUnit.SECONDS.sleep(1);
      }
      // 拿到口紅后再拿鏡子      ------------------------改進---------------------------
      synchronized (mirror) {
        System.out.println(userName + "拿到了鏡子");
      }
    }
    // 如果選擇1方式化妝
    if (choice == 1) {
      // 同步代碼塊的鎖,在同步代碼塊有效
      synchronized (mirror) {
        System.out.println(userName + "拿到了鏡子");
        TimeUnit.SECONDS.sleep(1);
      }
      // 拿到鏡子后再拿口紅      ------------------------改進---------------------------
      synchronized (lipStick) {
        System.out.println(userName + "拿到了口紅");
      }
    }
  }
}

通過及時釋放鎖,也就是縮小同步代碼塊的范圍,我們使用鎖結束后及時釋放,這樣是一種解決死鎖的方式,通過這個例子我們以后編寫代碼就會警惕鎖的同步代碼的范圍。

看完上述內容,你們對通俗易懂的Java死鎖代碼示例有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

利辛县| 姜堰市| 阿城市| 兴海县| 遵化市| 阿拉善左旗| 德钦县| 蓝田县| 湘潭市| 新巴尔虎右旗| 长子县| 略阳县| 天水市| 靖远县| 巴东县| 阿图什市| 隆昌县| 安图县| 永州市| 鄂尔多斯市| 福贡县| 维西| 枞阳县| 冷水江市| 昌平区| 新安县| 咸丰县| 新津县| 邛崃市| 中牟县| 临清市| 无极县| 屯门区| 福泉市| 青岛市| 绥滨县| 永寿县| 东至县| 商洛市| 延寿县| 温宿县|