线上的 Java 程序发生死锁,怎样定位?
先自己想一想,再看参考要点
参考要点
- 用阻塞式的锁时,死锁线程几乎不耗 CPU(例如等待 synchronized 的线程处于 BLOCKED),现象是 CPU 低而请求全部卡住
- 用 jstack 或 jcmd \<pid> Thread.print 打印线程栈,末尾会报告 Found one Java-level deadlock,列出各线程等待的锁和持有者
- 程序中也可以定时调用 ThreadMXBean.findDeadlockedThreads() 检测并告警,但它检测不到包含虚拟线程的死锁环和 Semaphore 这类不可重入锁的自死锁
- JVM 不会自动解除死锁,卡在 synchronized 上的线程无法中断,通常只能重启,所以要靠固定加锁顺序或 tryLock 预防