java多线程死锁本质是循环等待,预防需统一锁序(如按identityhashcode或主键升序)、用trylock设超时并回退、减小锁粒度、启用jvm死锁检测。

Java 中多线程交叉申请资源导致死锁,本质是多个线程以不同顺序争夺同一组锁,形成循环等待链。预防的关键不是“不加锁”,而是让加锁行为可预测、可控制、有退路。
统一锁获取顺序
这是最直接有效的手段。只要所有线程对同一组资源始终按相同顺序加锁,循环等待条件就被打破。
- 用 System.identityHashCode() 为锁对象生成唯一整数标识,每次先锁哈希值小的那个对象
- 避免在业务代码里硬写
synchronized(a) { synchronized(b) { ... } },应封装成工具方法,例如:lockInOrder(lockA, lockB, () -> { /* 临界区逻辑 */ }); - 若资源是数据库行或业务实体,可约定按主键 ID 升序加锁,而非按参数传入顺序
使用带超时的锁机制
即使顺序偶尔出错,也能及时中断,避免无限阻塞。
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- 用 ReentrantLock.tryLock(long, TimeUnit) 替代
synchronized,设置合理超时(如 100–500ms) - 获取失败时,必须主动释放已持有的锁,再重试或降级处理,不能继续等待
- 配合 Thread.interrupted() 检查中断状态,增强响应性
减少锁粒度与嵌套层级
交叉申请往往发生在多层同步块中。越少嵌套,越难形成环路。
- 优先用 ConcurrentHashMap、CopyOnWriteArrayList 等线程安全集合,避免手动加锁
- 用 AtomicInteger、AtomicReference 替代
int + synchronized计数场景 - 若需协调多个操作,考虑 StampedLock 的乐观读,或 Phaser 替代多层 wait/notify
启用死锁检测与监控
预防为主,但线上仍需兜底。早发现比等用户反馈更可靠。
- 开发阶段加 JVM 参数:
-XX:+PrintConcurrentLocks -XX:+UnlockDiagnosticVMOptions - 运行时调用 ManagementFactory.getThreadMXBean().findDeadlockedThreads() 定期扫描
- Spring Boot 应用中,可配置定时任务输出结果到日志,结合告警触发人工介入
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










