Skip to content

死锁相关

一、死锁产生场景

1. 定义

多个线程互相持有对方需要的锁,互相等待释放资源,所有线程永久阻塞,程序卡死无法继续执行。 核心诱因:线程需要同时获取多把锁,且加锁顺序不一致。

2. 标准死锁代码示例

java
Object A = new Object();
Object B = new Object();

Thread t1 = new Thread(() -> {
    synchronized (A) {
        System.out.println("lock A");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        synchronized (B) {
            System.out.println("lock B");
            System.out.println("操作...");
        }
    }
}, "t1");

Thread t2 = new Thread(() -> {
    synchronized (B) {
        System.out.println("lock B");
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        synchronized (A) {
            System.out.println("lock A");
            System.out.println("操作...");
        }
    }
}, "t2");

t1.start();
t2.start();
  • t1持有锁A,等待锁B;
  • t2持有锁B,等待锁A;
  • 双方互相等待,永久阻塞,形成死锁。

二、JDK命令行排查工具(线上首选)

1. jps

作用:列出当前所有JVM运行进程,获取Java进程PID。 执行命令:

shell
jps

输出示例:

46032 Deadlock
30560 Jps

46032 为死锁程序进程ID。

2. jstack

作用:打印指定进程所有线程堆栈,自动检测并标注死锁。 执行命令:

shell
jstack -l 46032

日志关键标识:Found one Java-level deadlock:,会打印:

  1. 阻塞线程名称;
  2. 当前线程已持有的锁;
  3. 当前线程正在等待的锁;
  4. 持有目标锁的对方线程。

完整排查步骤

  1. jps 获取Java程序进程PID;
  2. jstack -l 进程号 打印线程堆栈;
  3. 检索日志中 deadlock 关键字,定位死锁线程与对应代码行。

三、可视化GUI排查工具

1. jconsole

  • 本质:基于JMX的GUI监控工具;
  • 功能:监控JVM内存、类加载、线程状态,可检测死锁;
  • 启动方式:JDK安装目录bin下执行 jconsole.exe

2. VisualVM(jvisualvm)

  • 功能:线程监控、内存快照、CPU占用分析、堆内存查看,自带死锁检测;
  • 启动方式:JDK bin目录执行 jvisualvm.exe
  • 优势:图形化展示线程持有/等待锁关系,定位更直观。

四、总结

  1. 死锁高发场景:多线程需要同时抢占多把锁,且加锁顺序混乱。
  2. 线上快速诊断方案:jps 查进程PID → jstack 导出线程栈,检索deadlock定位死锁代码。
  3. 本地调试可视化工具:jconsole、VisualVM,图形化查看线程锁依赖关系。

五、面试高频问答

  1. 问:什么场景容易产生死锁?答: 多个线程需要同时获取多把锁,且线程之间加锁顺序不一致,互相持有对方依赖的锁,形成循环等待。

  2. 问:线上程序出现死锁,如何排查?答: 先用jps获取Java进程PID,再执行jstack打印线程堆栈,日志会自动输出死锁线程、持有锁、等待锁与对应代码位置;本地可使用jconsole、VisualVM可视化排查。

  3. 问:jps和jstack各自作用?答: jps列出所有运行的JVM进程,拿到进程ID;jstack打印进程内全部线程堆栈,自动识别并打印死锁信息。

Powered by VitePress 1.6.4 | 持续更新中