jstack可自动检测并标出死锁位置:先用jps -l获取pid,再执行jstack ,末尾“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></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"
这段信息直接告诉你哪两个(或多个)线程互相等待对方持有的锁,无需人工逐行分析堆栈。
结合线程堆栈定位问题代码
找到死锁线程名后,回溯该线程的完整堆栈(在 jstack 输出中搜索 "Thread-0" 或对应名称):
- 重点关注
at行,尤其是调用synchronized方法、ReentrantLock.lock()或wait()/notify()的位置 - 对比两个死锁线程各自持有了什么锁、又在等什么锁——通常暴露了加锁顺序不一致的问题
- 例如:Thread-0 先锁 A 再尝试锁 B,Thread-1 却先锁 B 再尝试锁 A,就极易触发死锁
生产环境注意事项
jstack 是轻量诊断工具,但仍有几点要注意:
- 尽量在业务低峰期执行,避免频繁调用影响性能(单次无妨)
- 若进程已卡死无法响应,
jstack可能挂住;此时可加-F参数强制获取(jstack -F <pid></pid>),但结果可能不完整 - 对于远程服务器,建议将输出重定向保存:
jstack <pid> > thread_dump.txt</pid>,方便离线分析或多人协作 - 如果使用 JDK 8u60+,还可配合
jcmd <pid> VM.native_memory summary</pid>排查是否内存耗尽导致假死,排除干扰
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











