← 每日面试题 学习看板

什么是活锁,和死锁有什么区别?

面试题/00java/02Java 并发编程/09编程实践与应用场景/什么是活锁,和死锁有什么区别?.md

面试记录 2026-10-26

题目:什么是活锁,和死锁有什么区别?

难度:low

标签:java/concurrency-practice, java/concurrency, general/knowledge, difficulty/low

评分:⭐⭐⭐⭐☆(4/5)

我的回答

活锁也是线程争抢资源产生的一个问题,危害性也非常高。活锁是线程持有资源,和其他线程出现争抢后就释放资源,然后重新再去争抢,多线程相互争抢然后被人抢就释放,导致多线程一直无法完成自己的任务一直在释放、争抢、释放循环,线程是 RUNNABLE 不是 BLOCKED 会空耗 CPU 资源;死锁则是线程相互阻塞,卡住无法继续下去大家谁也不释放自己持有的资源互相等待,线程 BLOCKED。

点评

优点:

不足:

完整讲解(权威版)

最后更新:2026-10-26 · 基于第 1 次作答

L1 · 30 秒速记

结论:活锁和死锁本质区别在线程状态——死锁 BLOCKED 卡住不动,活锁 RUNNABLE 空转但不推进。 关键词:BLOCKED vs RUNNABLE · 状态循环 · 随机退避 边界:三者都可能演化为饥饿,监控上靠线程状态分布 + CPU 使用区分

L2 · 核心讲解

核心考点定位:能否准确区分活锁、死锁、饥饿三种并发故障,抓住各自的状态机特征和危害方式。

机制链(3 环):

  1. 多线程争抢资源 → 线程状态机分岔:一方"释放重抢"进入活循环 vs 一方"占着不放"进入阻塞 → 状态决定危害方式
  2. 活锁的"释放重抢"模式 → 双方状态同步退让,谁也无法独占资源 → RUNNABLE 空耗 CPU 但业务零推进
  3. 死锁的"占着不放"模式 → 循环等待形成闭环,任一条件不满足即崩 → BLOCKED 堆积,JVM 内置 Found one Java-level deadlock 检测

证据锚点(去重 ≥6):

对比与权衡:

故障类型线程状态CPU 消耗是否推进检测手段解决方式
死锁BLOCKED低(等待)否jstack 检测 Found one Java-level deadlockkill / dump 栈分析后修复
活锁RUNNABLE高(空转)否线程 RUNNABLE 堆积 + CPU 高 + 业务 QPS 不涨随机退避(jitter / back-off)破坏循环
饥饿RUNNABLE/BLOCKED不定否长时间无业务指标变化公平锁 / 优先级随机化

常见误区:

  1. 错误:"活锁就是死锁的另一种说法" → 正确:两者状态不同(BLOCKED vs RUNNABLE),危害方式不同(等待 vs 空耗) → 为什么:混淆会让排查方向偏,活锁要靠 CPU 定位而不是等 jstack 报
  2. 错误:"活锁一定会自动恢复" → 正确:活锁可能长期持续,且可能演化为饥饿(其他线程永远拿不到资源) → 为什么:循环对称性未被打破前不会自愈
  3. 错误:"死锁靠 jstack 检测,活锁无解" → 正确:活锁可通过随机退避破坏循环对称性,让双方退让时间错开 → 为什么:只要打破循环同步,双方就能自然走出活循环

适用边界:

延伸追问(≥3)

  1. 线上活锁怎么监控和识别?
  1. JVM 有内置的活锁检测吗?
  1. 活锁怎么避免?

面试者参考回答(400–700 字)

【结论】 活锁和死锁本质区别在线程状态——死锁 BLOCKED 卡住不动,活锁 RUNNABLE 空转但不推进。

【三点】

第一,死锁:多个线程互相持有对方需要的资源,都进入 BLOCKED 状态等待对方释放,谁也不动,不消耗 CPU 也不推进。典型触发是四条件同时满足(互斥、占有且等待、不可剥夺、循环等待),线上靠 jstack 抓栈定位,JVM 内置 Found one Java-level deadlock 检测。

第二,活锁:线程都在主动变化状态试图推进,但状态变化恰好让彼此都无法前进,形成活循环——比如两个线程都在让步给对方,各自向左再向右反复退让。线程状态是 RUNNABLE 而不是 BLOCKED,所以空耗 CPU 资源,但业务实际不推进。这是活锁和死锁最大的差异:死锁"卡住不动",活锁"忙而不进"。

第三,监控识别与解法:死锁看 BLOCKED 堆积 + jstack 检测;活锁看 RUNNABLE 堆积 + CPU 高 + 业务指标无推进(QPS 不涨)。解法上死锁只能被外部打破(kill / dump 栈分析后修复);活锁靠随机退避(back-off with jitter)破坏循环对称性,让双方退让时间错开自然退出;饥饿靠公平锁或优先级随机化。

【边界】 三者都可能演化为饥饿——死锁若被中断可能变活锁;活锁若循环对称性未打破长期存在可能演化为饥饿(其他线程永远拿不到资源)。所以设计上要一开始就选无锁或公平锁避免这些问题。


作答历史

日期评分备注
2026-10-26⭐⭐⭐⭐☆首次作答