JJava 知识库
JAVA INTERVIEW

高频面试题

Java多线程进阶约 2 分钟

线上服务突然有一批请求永久卡住,你怀疑 Java 死锁,会怎么快速确认、止损和修复?

参考回答约 2 分钟 · 口语表达
我的判断

怀疑死锁时先用线程快照确认锁等待环,止损恢复流量,再通过统一加锁顺序和缩小临界区根治。

我会连续执行 jcmd <pid> Thread.print -l 或抓取线程转储。JVM 如果检测到 Java monitor 死锁,会直接列出参与线程、等待的锁和持有者;否则也会沿大量 BLOCKED 线程手工追锁。把线程名和 trace 对上,确认是业务锁、类初始化锁还是第三方库。

线上请求已经堆积时,先停止向问题实例分流,限制重试风暴;Java 内部锁通常无法安全地从外部释放,保存现场后重启实例往往比继续等待更可靠。

修复会把资源排序后按同一顺序加锁,例如总是先锁较小的账户 ID;移出锁内 RPC、数据库和日志 IO,减少嵌套锁。确实无法固定顺序时,用 tryLock(timeout) 失败后释放已持有资源并重试,但重试次数必须有限。

回归测试会并发运行两条相反业务路径,持续检查线程状态和超时,而不是只写一个顺序执行的单测。

容易答偏踩坑误区
  • 看到很多 WAITING 就判死锁。 线程池空闲、队列等待本来就是 WAITING。
  • 只给锁加超时。 如果失败后不释放前面拿到的资源,仍然可能形成活锁或数据错误。
  • 重启后不保留线程转储。 现场消失后很难确认真正的锁环。