记录面试问题之 ---- 死锁排查

喜欢而已 提交于 2020-03-03 16:37:57

面试常见问题之如何排查死锁

**如何产生死锁 :
1. 共享资源
2. 循环等待
3. 请求保持
4. 不可抢占
**

考察多线程,在代码中如果使用到多线程,就应该多注意是否会产生死锁:如下例子


```java

import java.util.concurrent.locks.ReentrantLock;

public class Code_dead_Thread  {

    public static void main(String[] args) {
        ReentrantLock lock = new ReentrantLock();
        ReentrantLock lock2 = new ReentrantLock();
        Thread thread = new Thread(new Thread_A(lock,lock2));
        Thread thread1 = new Thread(new Thread_B(lock,lock2));
        thread.start();
        thread1.start();
    }

}
class Thread_A implements Runnable{

    private ReentrantLock lock ;
    ReentrantLock lock2 ;
    Thread_A(ReentrantLock lock,ReentrantLock lock2){
        this.lock = lock;
        this.lock2 = lock2;
    }
    @Override
    public void run() {
        lock.lock();
        System.out.println("lock");
        try {
            Thread.sleep(1000);
            lock2.lock();
            System.out.println("Thread_A");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock2.unlock();
            lock.unlock();
        }
    }
}

class Thread_B implements Runnable{

    private ReentrantLock lock ;
    ReentrantLock lock2 ;
    Thread_B(ReentrantLock lock,ReentrantLock lock2){
        this.lock = lock;
        this.lock2 = lock2;
    }
    @Override
    public void run() {
        lock2.lock();
        try {
            System.out.println("lock2");
            Thread.sleep(1000);
            lock.lock();
            System.out.println("Thread_A");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.unlock();
            lock2.unlock();
        }
    }
}

定义了两个reentrantLock lock ,lock2,而有两个线程A and B ,分别有两个属性,在传入的时候,放入两个锁,而A 先获取到lock,让它等待1000毫秒,然后去获取lock2,在线程thread2中,先去获取到lock2,然后去获取lock,这个时候,就会发生死锁 — 原因:请求和保持,都等到拿到对方的锁,才能够释放*如果在代码中,发生这种问题,我们该怎么查看呢? 到底那个地方会发生死锁,这个时候就需要jdk自带的jvm的内存查看工具 ,介绍两种:


项目启动后,进入死锁状态

第一种方式: jps + jstack
在终端输入jps ,之后出现有那些正在运行的线程
jstack 可以查看有哪些命令,我们使用jstack -l pid
可以看到发生了deadlock,下面是原因**第二种方式: jconsole **

弹出控制台
点击线程,然后点击检索死锁有两个线程处于死锁状态,我们查看日志,发现在线程A  的run方法中发生,代码行是 31,所以我们既可以定位到死锁位置,然后修改。希望能够帮到你,记录一次

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!