如何在 Java 中避免死鎖?


在 Java 中,死鎖是一種程式設計情況,在這種情況下,兩個或更多個執行緒永久被阻塞。死鎖條件將出現在至少兩個執行緒和兩個或更多個資源中。

如何避免死鎖

  • 避免巢狀鎖 − 死鎖主要發生在我們向多個執行緒提供鎖的時候。如果我們已經向一個執行緒提供了鎖,則避免向多個執行緒提供鎖。

  • 避免不必要的鎖 − 我們只能鎖住那些必需的成員。不必要地鎖住可能會導致死鎖。

  • 使用 Thread.join() − 當一個執行緒等待另一個執行緒完成時,死鎖條件就會出現。如果出現此條件,我們可以在執行將花費的最長時間內使用 Thread.join()。

示例

public class DeadlockTest {
   public static void main(String[] args) throws InterruptedException {
      Object obj1 = new Object();
      Object obj2 = new Object();
      Object obj3 = new Object();
      Thread t1 = new Thread(new SyncThread(obj1, obj2), "t1");
      Thread t2 = new Thread(new SyncThread(obj2, obj3), "t2");
      t1.start();
      Thread.sleep(2000);
      t2.start();
      Thread.sleep(2000);
   }
}
class SyncThread implements Runnable {
   private Object obj1;
   private Object obj2;
   public SyncThread(Object o1, Object o2){
      this.obj1=o1;
      this.obj2=o2;
   }
   @Override
   public void run() {
      String name = Thread.currentThread().getName();
      System.out.println(name + " acquiring lock on " + obj1);
      synchronized (obj1) {
         System.out.println(name + " acquired lock on " + obj1);
         work();
      }
      System.out.println(name + " released lock on " + obj1);
      System.out.println(name + " acquiring lock on " + obj2);
      synchronized (obj2) {
         System.out.println(name + " acquired lock on " + obj2);
         work();
      }
      System.out.println(name + " released lock on " + obj2);
      System.out.println(name + " finished execution.");
   }
   private void work() {
      try {
         Thread.sleep(5000);
      } catch (InterruptedException ie) {
         ie.printStackTrace();
      }
   }
}

輸出

t1 acquiring lock on java.lang.Object@27a54c50
t1 acquired lock on java.lang.Object@27a54c50
t2 acquiring lock on java.lang.Object@2ee6a5aa
t2 acquired lock on java.lang.Object@2ee6a5aa
t1 released lock on java.lang.Object@27a54c50
t1 acquiring lock on java.lang.Object@2ee6a5aa
t2 released lock on java.lang.Object@2ee6a5aa
t2 acquiring lock on java.lang.Object@20214e06
t1 acquired lock on java.lang.Object@2ee6a5aa
t2 acquired lock on java.lang.Object@20214e06
t1 released lock on java.lang.Object@2ee6a5aa
t2 released lock on java.lang.Object@20214e06
t1 finished execution.
t2 finished execution.

更新時間: 2023 年 11 月 24 日

5000 多次瀏覽

開啟你的職業生涯

透過完成課程獲得認證

開始
廣告
© . All rights reserved.