Java如何定位死锁?

本文通过一个简单的Java死锁程序实例,展示了如何利用jstack工具进行死锁定位。通过jps找到进程ID,然后使用jstack查看线程栈信息,分析出线程间的锁持有与等待状态,从而定位到死锁问题。

Java如何定位死锁?

死锁模拟

在分析介绍之前,先以一个基本的死锁程序为例,我在这里只用了两个嵌套的 synchronized 去获取锁,具体如下:

package com.javapractice.concurrent;

public class DeadLockDemo extends Thread {

    private String lock1;
    private String lock2;

    public DeadLockDemo(String lock1, String lock2) {
        this.lock1 = lock1;
        this.lock2 = lock2;
    }

    @Override
    public void run() {
        synchronized (lock1) {
            System.out.println(Thread.currentThread().getName() + "获得资源: " + lock1);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (lock2) {
                System.out.println(Thread.currentThread().getName() + "获得资源: " + lock2);
            }
        }
    }

    public static void main(String[] args) {
        String lock1 = "lock1";
        String lock2 = "lock2";
        new DeadLockDemo(lock1, lock2).start();
        new DeadLockDemo(lock2, lock1).start();
    }
}

运行结果如下,可以发现出现了死锁,Thread-1在等待lock1,而Thread-0在等待lock2:

Thread-1获得资源: lock2
Thread-0获得资源: lock1

定位死锁

下面来模拟问题定位,我使用的是最常见的 jstack。

首先,可以使用 jps 或者系统的 ps 命令、任务管理器等工具,确定进程 ID。在终端中输入jsp后,发现DeadLockDemo程序的pid是83208

jps
83208 DeadLockDemo

然后,调用 jstack 获取线程栈:

jstack your_pid

此处场景在终端输入:

jstack 83208

在这里插入图片描述
最后,结合代码分析线程栈信息。上面这个输出非常明显,Thread-1正在等待锁<0x000000076ac26f50>,已经持有锁<0x000000076ac26f88>;而Thread-0正在等待锁<0x000000076ac26f88>,已经持有锁<0x000000076ac26f50>。 jstack 本身也会把类似的简单死锁信息抽取出来,直接打印出来。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值