在面試過程中面試官可能會問你關於鎖的知識,並讓你手寫一個死鎖的案例。下面我們來寫一個簡單的小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. 避免使用多個鎖
......