Java中死鎖的簡單例子及其避免


死鎖:當一個線程永遠地持有一個鎖,並且其他線程都嘗試獲得這個鎖時,那么它們將永遠被阻塞。比如,線程1已經持有了A鎖並想要獲得B鎖的同時,線程2持有B鎖並嘗試獲取A鎖,那么這兩個線程將永遠地等待下去。

我們來看一個死鎖的簡單例子:

 1 public class DeadLockTest
 2 {
 3     private static Object A = new Object(), B = new Object();
 4 
 5     public static void main(String[] args)
 6     {
 7         new Thread(() -> {
 8             System.out.println("線程1開始執行...");
 9             synchronized (A)
10             {
11                 try
12                 {
13                     System.out.println("線程1拿到A鎖");
14                     //休眠兩秒讓線程2有時間拿到B鎖
15                     Thread.sleep(2000);
16                 } catch (Exception e)
17                 {
18                     e.printStackTrace();
19                 }
20                 synchronized (B)
21                 {
22                     System.out.println("線程1拿到B鎖");
23                 }
24             }
25         }).start();
26         
27         new Thread(() -> {
28             System.out.println("線程2開始執行...");
29             synchronized (B)
30             {
31                 try
32                 {
33                     System.out.println("線程2拿到B鎖");
34                     //休眠兩秒讓線程1有時間拿到A鎖
35                     Thread.sleep(2000);
36                 } catch (Exception e)
37                 {
38                     e.printStackTrace();
39                 }
40                 synchronized (A)
41                 {
42                     System.out.println("線程2拿到A鎖");
43                 }
44             }
45         }).start();
46         
47     }
48 }

 

運行結果:

 

從運行結果可看到,線程1拿到了A鎖,並嘗試去獲取B鎖,與此同時線程2拿到了B鎖並嘗試去獲取A鎖,此時線程1和線程2就陷入了無限的等待,形成死鎖。

那么要怎么預防死鎖呢?下面介紹幾個常見方法:

1、避免一個線程同時獲取多個鎖

2、避免一個線程在鎖內同時占用多個資源,盡量保證每個鎖只占用一個資源

3、嘗試使用定時鎖,使用lock.tryLock來代替使用內置鎖。

詳情可參考《Java並發編程實戰》


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM