使用Java代碼手寫死鎖


在面試過程中面試官可能會問你關於鎖的知識,並讓你手寫一個死鎖的案例。下面我們來寫一個簡單的小Demo來實現一個死鎖。

死鎖案例

 1 public class DeadLockDemo extends Thread{
 2 
 3     String lockA ;
 4     String lockB;
 5     public DeadLockDemo(String name,String lockA,String lockB){
 6         super(name);
 7         this.lockA = lockA;
 8         this.lockB = lockB;
 9     }
10 
11     public void run() {
12         synchronized (lockA){
13             System.out.println(Thread.currentThread().getName() + "拿到了" + lockA + ",等待拿到" + lockB);
14             try {
15                 Thread.sleep(1000);
16                 synchronized (lockB){
17                     System.out.println(Thread.currentThread().getName() + "拿到了" + lockB);
18                 }
19             } catch (InterruptedException e) {
20                 e.printStackTrace();
21             }
22 
23         }
24     }
25 
26     public static void main(String[] args){
27         String lockA = "lockA";
28         String lockB = "lockB";
29         DeadLockDemo threadA = new DeadLockDemo("ThreadA", lockA, lockB);
30         DeadLockDemo threadB = new DeadLockDemo("ThreadB", lockB, lockA);
31         threadA.start();
32         threadB.start();
33         try {
34             threadA.join();
35             threadB.join();
36         } catch (InterruptedException e) {
37             e.printStackTrace();
38         }
39     }
40 }

這段代碼 顯而易見會block住 來看結果

ThreadA拿到了lockA,等待拿到lockB
ThreadB拿到了lockB,等待拿到lockA

並且程序是一直運行着的狀態,那么程序出了這種狀況應該怎么去排查呢?對於簡單的案例我們直接用jstack就可以來查看具體是哪里的問題了

排查死鎖

首先使用jps查看當前程序的進程的ID

然后使用jstack來打印信息

 

 

從上面可以看到兩個線程被block住了 然后自己去查看出錯的代碼進行分析

怎么預防死鎖

死鎖的產生讓人頭疼,那么怎么去預防死鎖呢?

預防死鎖得先知道死鎖產生的條件

1.互斥(一個資源一次只能被一個進程訪問)

2. 請求與保持(一個進程因請求資源而阻塞時,對自己的資源不釋放)

3.不可剝奪(進程已獲得的資源,不能被搶占剝奪)

4. 循環等待(進程間形成等待的循環關系)

那么我們只要破壞其中的一項就不會產生死鎖。

預防的方法主要有:

1. 著名的銀行家算法

2. 可以使用帶時間的tryLock(long timeout, TmeUnit unit)方法

3. 避免使用多個鎖

......


免責聲明!

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



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