1. 找到目标 Java 进程的 PID使用jps命令JDK 自带或ps命令Linux找到你的 Java 应用的进程 ID。bashjps -l # 或 ps aux | grep java输出示例text12345 com.example.MyApp2. 运行 jstack 命令bashjstack pid如果需要更详细的锁信息包括java.util.concurrent中的锁可以加-l参数bashjstack -l pid如果进程响应慢或需要避免影响可以使用-F强制打印某些情况。3. 查看死锁检测报告当jstack检测到死锁时会在输出的末尾通常最后几行明确打印类似如下的信息textFound one Java-level deadlock: Thread-1: waiting to lock monitor 0x00007f8c8c001e00 (object 0x00000000d5f8a4a8, a java.lang.Object), which is held by Thread-0 Thread-0: waiting to lock monitor 0x00007f8c8c001d00 (object 0x00000000d5f8a4b0, a java.lang.Object), which is held by Thread-1 Java stack information for the threads listed above: Thread-1: at com.example.MyTask.run(MyTask.java:23) - waiting to lock 0x00000000d5f8a4a8 (a java.lang.Object) - locked 0x00000000d5f8a4b0 (a java.lang.Object) Thread-0: at com.example.MyTask.run(MyTask.java:23) - waiting to lock 0x00000000d5f8a4b0 (a java.lang.Object) - locked 0x00000000d5f8a4a8 (a java.lang.Object) Found 1 deadlock.关键信息解读Found one Java-level deadlock明确表示存在死锁。列出每个死锁线程的名称、正在等待的锁、已经持有的锁。提供堆栈跟踪指出代码中具体哪一行导致了死锁。还会显示锁对象的地址和类型。4. 手动分析如果自动检测未显示极少数情况下比如使用了自定义同步器jstack可能无法自动识别死锁此时需要手动分析搜索BLOCKED状态的线程grep BLOCKED或观察线程状态java.lang.Thread.State: BLOCKED。查看每个 BLOCKED 线程的- waiting to lock ...和- locked ...信息。画出锁依赖图看是否存在循环等待。5. 注意事项权限jstack需要与目标进程相同的用户权限或者使用sudo。容器环境如果 Java 进程运行在 Docker 容器内需要进入容器或使用docker exec执行jstack。轻量级影响jstack会暂停虚拟机的某些行为尤其是在安全点但通常对生产环境影响较小。-l选项开销稍大。死锁的瞬时性如果死锁只出现一瞬间可以增加采样频率或结合jstack pid stack.log多次记录。6. 自动化检测脚本示例你可以写一个简单的脚本定期检测死锁bash#!/bin/bash pid$(jps -l | grep YourAppName | awk {print $1}) jstack $pid | grep -A 20 Found one Java-level deadlock if [ $? -eq 0 ]; then echo Deadlock detected at $(date) deadlock.log jstack $pid deadlock.log fi总结使用jstack检测死锁非常简单获取 PID - 运行jstack pid- 查看输出末尾的 Found one Java-level deadlock 段落。它不仅能检测还能直接告诉你哪个线程锁了哪个对象、正在等待哪个对象以及对应的代码位置。这是生产环境排查死锁问题的首选方法。