根本区别在于:死锁几乎不消耗cpu,活锁则持续拉高cpu使用率;死锁线程处于blocked/waiting状态、完全停滞,活锁线程保持runnable状态、空转重试却无进展。

根本区别在于:死锁几乎不消耗 CPU,活锁则持续拉高 CPU 使用率。
死锁的 CPU 表现:低占用 + 完全停滞
死锁线程处于 BLOCKED 或 WAITING 状态,被 JVM 挂起,不再参与调度。它们不执行任何代码,也不争夺 CPU 时间片:
- jstack 输出中可见 “waiting for monitor entry” 或 “in Object.wait()” 等阻塞标记
- CPU 占用率平稳偏低,即使线程数多,整体负载也无明显飙升
- 业务日志完全中断,无新请求处理痕迹
活锁的 CPU 表现:高占用 + 原地空转
活锁线程始终处于 RUNNABLE 状态,持续运行却无法推进业务逻辑:
- jstack 显示线程卡在某个 while 循环、条件判断或 sleep 前的检查点(如 “at com.example.Xxx.retryLoop”)
- CPU 使用率异常升高,常伴随“高负载但零吞吐”的现象
- 日志里反复出现相同失败记录(如 “tryLock failed, retrying…”),无成功落地动作
为什么这个区别很关键
它直接决定了排查路径:
- 看到 CPU 飙升 + jstack 全是 RUNNABLE → 优先查活锁,重点看重试逻辑、忙等待、协作退让代码
- 看到 CPU 平稳 + 大量线程 BLOCKED → 锁顺序、循环等待、资源竞争是首要怀疑对象
- 监控中若同时出现高 CPU 和业务超时/积压,活锁可能性远高于死锁
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











