Java-并发编程-死锁
- IT业界
- 2025-08-28 16:27:02

🔍 死锁排查步骤详解(以 Java 应用为例)
1️⃣ 快速确认死锁现象 现象:应用无响应、接口超时、CPU 占用低但线程阻塞。日志线索:查看日志中是否存在 java.lang.Thread.State: BLOCKED 或 deadlock 关键字。
2️⃣ 获取线程转储(Thread Dump)
🔧 方法一:命令行工具
# 查找 Java 进程 PID jps -l # 生成线程转储(替换 PID) jstack -l <PID> > thread_dump.txt🔧 方法二:JDK 图形化工具
使用 jconsole 或 VisualVM 连接进程,直接查看线程状态和检测死锁。3️⃣ 分析线程转储
🔍 关键步骤:
搜索 deadlock:线程转储开头会标记检测到的死锁。
Found one Java-level deadlock: ============================= "Thread-1": waiting to lock monitor 0x00007f8d6c0038b8 (object 0x000000076ab66e50, a java.lang.Object), which is held by "Thread-0" "Thread-0": waiting to lock monitor 0x00007f8d6c0060b8 (object 0x000000076ab66e60, a java.lang.Object), which is held by "Thread-1"分析线程状态:
BLOCKED:线程等待获取锁。持有锁信息:locked <0x000000076ab66e50> 表示当前线程持有的锁。等待锁信息:waiting to lock <0x000000076ab66e60> 表示线程正在等待的锁。4️⃣ 代码复现与调试
🔧 复现死锁代码示例:
public class DeadlockDemo { private static final Object lockA = new Object(); private static final Object lockB = new Object(); public static void main(String[] args) { new Thread(() -> { synchronized (lockA) { try { Thread.sleep(100); } catch (InterruptedException e) {} synchronized (lockB) {} // 等待 lockB } }).start(); new Thread(() -> { synchronized (lockB) { synchronized (lockA) {} // 等待 lockA } }).start(); } }🔍 调试关键点:
锁顺序:检查不同线程是否以相同顺序获取多个锁。锁粒度:是否过度使用粗粒度锁(如 synchronized 修饰整个方法)。5️⃣ 预防与解决策略 策略说明固定锁顺序所有线程按全局固定顺序获取锁(如按对象哈希值排序)避免循环等待。超时机制使用 tryLock(long timeout, TimeUnit unit) 设置锁获取超时,避免无限等待。死锁检测通过工具(如 Arthas)定期扫描线程状态,提前预警。减少锁粒度使用细粒度锁(如 ConcurrentHashMap 分段锁)或乐观锁(CAS)。避免嵌套锁尽量减少一个线程同时持有多个锁的场景。
6️⃣ 工具增强 Arthas:实时监控线程状态,动态追踪锁竞争。# 查看当前线程阻塞状态 thread -b JProfiler:图形化分析线程争用和锁持有关系。
📊 死锁分析流程图 应用出现卡顿或无响应 → 生成线程转储(jstack/jcmd) → 查找 "deadlock" 或 "BLOCKED" 线程 → 分析锁持有/等待链 → 修改代码(调整锁顺序/超时机制) → 测试验证
通过以上步骤,可快速定位并解决死锁问题,确保应用的高可用性。
Java-并发编程-死锁由讯客互联IT业界栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“Java-并发编程-死锁”