jstack可自动检测并标出死锁位置:先用jps -l获取PID,再执行jstack <pid>,末尾“Found one Java-level deadlock”区块会明确列出互相等待的线程、锁地址及阻塞源码行,结合堆栈定位加锁顺序不一致问题。

直接用 jstack 查看 Java 进程的线程快照,它会自动检测并明确标出死锁位置——这是最简单有效的第一步。
确认目标 Java 进程 PID
死锁排查的前提是知道要分析哪个 JVM 进程。常用方法:
- 运行
jps -l列出所有 Java 进程及其主类或 JAR 路径,快速定位 - 若进程名不明确,可结合
ps aux | grep java查看启动参数辅助判断 - 在容器环境中(如 Docker),需先进入容器再执行
jps,或通过docker top找宿主机 PID 后映射使用
执行 jstack 并关注死锁提示
对目标 PID 执行:jstack <pid>
输出中只要存在死锁,jstack 会在末尾单独给出清晰报告,类似:
Found one Java-level deadlock: ============================= "Thread-1": waiting to lock monitor 0x00007f8a1c00a9e8 (object 0x000000076b5a2a40, a java.lang.Object), which is held by "Thread-0" "Thread-0": waiting to lock monitor 0x00007f8a1c00b0d8 (object 0x000000076b5a2a50, a java.lang.Object), which is held by "Thread-1"
这段信息直接告诉你哪两个(或多个)线程互相等待对方持有的锁,无需人工逐行分析堆栈。
立即学习“Java免费学习笔记(深入)”;
结合线程堆栈定位问题代码
找到死锁线程名后,回溯该线程的完整堆栈(在 jstack 输出中搜索 "Thread-0" 或对应名称):
- 重点关注
at行,尤其是调用synchronized方法、ReentrantLock.lock()或wait()/notify()的位置 - 对比两个死锁线程各自持有了什么锁、又在等什么锁——通常暴露了加锁顺序不一致的问题
- 例如:Thread-0 先锁 A 再尝试锁 B,Thread-1 却先锁 B 再尝试锁 A,就极易触发死锁
生产环境注意事项
jstack 是轻量诊断工具,但仍有几点要注意:
- 尽量在业务低峰期执行,避免频繁调用影响性能(单次无妨)
- 若进程已卡死无法响应,
jstack可能挂住;此时可加-F参数强制获取(jstack -F <pid>),但结果可能不完整 - 对于远程服务器,建议将输出重定向保存:
jstack <pid> > thread_dump.txt,方便离线分析或多人协作 - 如果使用 JDK 8u60+,还可配合
jcmd <pid> VM.native_memory summary排查是否内存耗尽导致假死,排除干扰


















