在面试过程中面试官可能会问你关于锁的知识,并让你手写一个死锁的案例。下面我们来写一个简单的小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. 避免使用多个锁
......