java如何避免程式死鎖

ckxllf 發表於 2019-09-26

  併發程式一旦死鎖,往往我們只能重啟應用。解決死鎖問題最好的辦法就是避免死鎖。

  死鎖發生的條件

  互斥,共享資源只能被一個執行緒佔用

  佔有且等待,執行緒 t1 已經取得共享資源 s1,嘗試獲取共享資源 s2 的時候,不釋放共享資源 s1

  不可搶佔,其他執行緒不能強行搶佔執行緒 t1 佔有的資源 s1

  迴圈等待,執行緒 t1 等待執行緒 t2 佔有的資源,執行緒 t2 等待執行緒 t1 佔有的資源

  避免死鎖的方法

  對於以上 4 個條件,只要破壞其中一個條件,就可以避免死鎖的發生。

  對於第一個條件 "互斥" 是不能破壞的,因為加鎖就是為了保證互斥。

  其他三個條件,我們可以嘗試

  一次性申請所有的資源,破壞 "佔有且等待" 條件

  佔有部分資源的執行緒進一步申請其他資源時,如果申請不到,主動釋放它佔有的資源,破壞 "不可搶佔" 條件

  按序申請資源,破壞 "迴圈等待" 條件

  使用管理類一次性申請所有的資源,破壞 "佔有且等待" 條件示例

  package constxiong.concurrency.a023;

  import java.util.HashSet;

  import java.util.Set;

  /**

  * 測試 一次性申請所有的資源,破壞 "佔有且等待" 條件示例

  * @author ConstXiong

  * @date 2019-09-24 14:04:12

  */

  public class TestBreakLockAndWait {

  //單例的資源管理類

  private final static Manger manager = new Manger();

  //資源1

  private static Object res1 = new Object();

  //資源2

  private static Object res2 = new Object();

  public static void main(String[] args) {

  new Thread(() -> {

  boolean applySuccess = false;

  while (!applySuccess) {

  //向管理類,申請res1和res2,申請失敗,重試

  applySuccess = manager.applyResources(res1, res2);

  if (applySuccess) {

  try {

  System.out.println("執行緒:" + Thread.currentThread().getName() + " 申請 res1、res2 資源成功");

  synchronized (res1) {

  System.out.println("執行緒:" + Thread.currentThread().getName() + " 獲取到 res1 資源的鎖");

  //休眠 1秒

  try {

  Thread.sleep(1000);

  } catch (Exception e) {

  e.printStackTrace();

  }

  synchronized (res2) {

  System.out.println("執行緒:" + Thread.currentThread().getName() + " 獲取到 res2 資源的鎖");

  }

  }

  } finally {

  manager.returnResources(res1, res2);//歸還資源

  }

  } else {

  System.out.println("執行緒:" + Thread.currentThread().getName() + " 申請 res1、res2 資源失敗");

  //申請失敗休眠 200 毫秒後重試

  try {

  Thread.sleep(200);

  } catch (Exception e) {

  e.printStackTrace();

  }

  }

  }

  }).start();

  new Thread(() -> {

  boolean applySuccess = false;

  while (!applySuccess) {

  //向管理類,申請res1和res2,申請失敗,重試

  applySuccess = manager.applyResources(res1, res2);

  if (applySuccess) {

  try { 無錫婦科醫院哪家好 http://www.xasgfk.cn/

  System.out.println("執行緒:" + Thread.currentThread().getName() + " 申請 res1、res2 資源成功");

  synchronized (res2) {

  System.out.println("執行緒:" + Thread.currentThread().getName() + " 獲取到 res1 資源的鎖");

  //休眠 1秒

  try {

  Thread.sleep(1000);

  } catch (Exception e) {

  e.printStackTrace();

  }

  synchronized (res1) {

  System.out.println("執行緒:" + Thread.currentThread().getName() + " 獲取到 res2 資源的鎖");

  }

  }

  } finally {

  manager.returnResources(res1, res2);//歸還資源

  }

  } else {

  System.out.println("執行緒:" + Thread.currentThread().getName() + " 申請 res1、res2 資源失敗");

  //申請失敗休眠 200 毫秒後重試

  try {

  Thread.sleep(200);

  } catch (Exception e) {

  e.printStackTrace();

  }

  }

  }

  }).start();

  }

  }

  /**

  * 資源申請、歸還管理類

  * @author ConstXiong

  * @date 2019-09-24 14:10:57

  */

  class Manger {

  //資源存放集合

  private Set


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69945560/viewspace-2658352/,如需轉載,請註明出處,否則將追究法律責任。


相關文章

每週開源點評:雲原生 Java、開源安全以及更多行業趨勢 Java

每週開源點評:雲原生 Java、開源安全以及更多行業趨勢

開源社群和行業趨勢的每週總覽。作為我在具有開源開發模型的企業軟體公司擔任高階產品營銷經理的角色的一部分,我為產品營銷人員、經理和其他影響者定期釋出有關開源社群,市場和行業趨勢的定期更新。 以下是該更新
夯實Java基礎系列11:深入理解Java中的回撥機制 Java

夯實Java基礎系列11:深入理解Java中的回撥機制

本系列文章將整理到我在GitHub上的《Java面試指南》倉庫,更多精彩內容請到我的倉庫裡檢視https://github.com/h2pl/Java-Tutorial喜歡的話麻煩點下Star哈文章首
夯實Java基礎系列13:深入理解Java中的泛型 Java

夯實Java基礎系列13:深入理解Java中的泛型

本系列文章將整理到我在GitHub上的《Java面試指南》倉庫,更多精彩內容請到我的倉庫裡檢視https://github.com/h2pl/Java-Tutorial喜歡的話麻煩點下Star、For
夯實Java基礎系列17:一文搞懂Java多執行緒使用方式、實現原理以及常見面試題 Java|面試

夯實Java基礎系列17:一文搞懂Java多執行緒使用方式、實現原理以及常見面試題

本系列文章將整理到我在GitHub上的《Java面試指南》倉庫,更多精彩內容請到我的倉庫裡檢視https://github.com/h2pl/Java-Tutorial喜歡的話麻煩點下Star哈文章首
夯實Java基礎系列19:一文搞懂Java集合類框架,以及常見面試題 Java|面試|框架

夯實Java基礎系列19:一文搞懂Java集合類框架,以及常見面試題

本系列文章將整理到我在GitHub上的《Java面試指南》倉庫,更多精彩內容請到我的倉庫裡檢視https://github.com/h2pl/Java-Tutorial喜歡的話麻煩點下Star哈文章首
夯實Java基礎系列20:從IDE的實現原理聊起,談談那些年我們用過的Java命令 Java

夯實Java基礎系列20:從IDE的實現原理聊起,談談那些年我們用過的Java命令

本系列文章將整理到我在GitHub上的《Java面試指南》倉庫,更多精彩內容請到我的倉庫裡檢視https://github.com/h2pl/Java-Tutorial喜歡的話麻煩點下Star哈文章首
夯實Java基礎系列22:一文讀懂Java序列化和反序列化 Java

夯實Java基礎系列22:一文讀懂Java序列化和反序列化

本系列文章將整理到我在GitHub上的《Java面試指南》倉庫,更多精彩內容請到我的倉庫裡檢視https://github.com/h2pl/Java-Tutorial喜歡的話麻煩點下Star哈文章首