java如何排查死锁?

死锁现象描述

现在有两把锁(排他锁),锁1和锁2,两个线程,线程A和线程B,线程A获取到锁1,线程B获取到锁2,此时线程A再去获取锁2,线程B再去获取锁1,就会造成死锁。

死锁在生产上表露出来的现象通常是cpu占用不高且响应缓慢

死锁问题排查

测试程序如下:

public class DeadLockTest {
    public static Object lock1 = new Object();

    public static Object lock2 = new Object();

    public static void main(String[] args) {

        new Thread(()->{
            synchronized (lock1) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                synchronized (lock2) {
                    System.out.println(111111);
                }
            }
        }).start();

        new Thread(()->{
            synchronized (lock2) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                synchronized (lock1) {
                    System.out.println(111111);
                }
            }
        }).start();
    }
}

在测试程序中很容易发现死锁问题,但是在生产上该如何定位呢?

第一步:定位问题

通过jps指令找到进程号
在这里插入图片描述
通过jstack <pid> 指令可以查看该进程的线程状态
在这里插入图片描述
注意:当生产发生问题时,通常会将此信息输出到文件中,可使用如下指令
jstack -l <pid> > <文件名>

在控制台最下面有死锁提示:
在这里插入图片描述

第二步:解决问题

产生死锁有四个必要条件,分别是资源互斥、环路等待、不可剥夺、请求并保持。破坏任一条件即可解决死锁。

  1. 资源互斥:如果资源可以共享,那么就不会互相阻塞,也就不会产生死锁了
  2. 环路等待:如果获取锁1和锁2的时候按照顺序获取,那么也不会产生死锁
  3. 不可剥夺:线程A获取锁2的时候直接剥夺线程B获取到的锁2
  4. 请求并保持:线程A发现锁2获取不到(设定一定的超时时间),则释放锁1,此时线程B可以获取到锁,运行完毕之后,线程A再重新执行。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

寻寻寻寻寻L

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值