Java中无并发死锁异常,JVM不抛异常,线程永久BLOCKED;需预防、检测与兜底:一用ThreadMXBean/jstack发现死锁,二统一锁序/tryLock/缩小同步范围预防,三通过健康检查、业务超时和JFR兜底。

一、运行时检测死锁(发现它)
利用 JVM 内置的死锁检测能力,主动扫描并获取线索:
- 用 ThreadMXBean.findDeadlockedThreads() 编程式检查:适合嵌入健康检查接口或定时监控任务
- 执行 jstack -l <pid>:输出中若出现 "Found one Java-level deadlock",即明确标识出死锁线程和锁依赖链
- 用 JConsole 或 VisualVM 连接进程,在“Threads”页直接看到标红的死锁线程组
二、编码层预防死锁(挡住它)
从根源上破坏死锁四条件中的至少一个,最有效的是打破“循环等待”和“占有并等待”:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 统一锁顺序:为所有锁对象定义全局唯一序号(如按 Class 名、字段名哈希或显式编号),所有线程严格按升序(或降序)获取锁
-
用 tryLock + 超时:改用
ReentrantLock.tryLock(1, TimeUnit.SECONDS),失败则释放已持锁并退避重试,避免无限等待 - 缩小同步范围:synchronized 块内不调用外部方法、不执行 I/O、不 sleep;把耗时操作移出临界区
-
减少锁数量:优先使用无锁工具(
AtomicInteger、ConcurrentHashMap)替代 synchronized 计数或缓存
三、上线后兜底策略(兜住它)
即使有预防,高并发复杂场景仍可能漏网。需设计可观测与应急机制:
- 在关键服务启动时注册 DeadlockHealthIndicator,供 /actuator/health 检查,告警通知运维
- 对核心交易流程设置 业务超时 + 强制中断:例如转账操作 5 秒未完成,主动 cancel 相关线程(注意:Thread.stop() 已废弃,推荐协作式中断 + 可响应的锁等待)
- 配置 JVM 参数 -XX:+PrintConcurrentLocks 或开启 JFR(Java Flight Recorder)录制锁竞争事件,便于事后回溯

















