轻量级锁通过cas抢锁并自旋等待,失败后升级为重量级锁;它在用户态完成同步,避免内核态切换开销,适用于短临界区、低频竞争场景。

Java 中轻量级锁通过 CAS 实现线程同步,核心在于“不挂起、先自旋、延后阻塞”,把昂贵的内核态切换压到最低。它不是彻底消灭竞争,而是让短时、低频的竞争在用户态快速解决,从而显著提升吞吐量。
轻量级锁怎么用 CAS 抢锁
当线程进入 synchronized 同步块时,JVM 先检查对象头是否为无锁状态(标志位 01);若是,就在当前线程栈帧里建一个锁记录,再用 CAS 尝试把对象头的 Mark Word 替换为指向该锁记录的指针:
- 替换成功 → 线程直接获得轻量级锁,继续执行,全程无挂起、无调度、无内核介入
- 替换失败 → 说明锁正被其他线程持有,此时不立即阻塞,而是进入自旋循环:反复用 CAS 检查对象头是否已恢复为无锁或原值
CAS 自旋为什么比挂起更高效
线程挂起涉及操作系统从用户态切到内核态,保存寄存器、刷新 TLB、触发调度器,一次切换通常耗时数百纳秒至微秒级;而 CAS 自旋只是 CPU 在用户态反复执行一条原子指令(如 cmpxchg),开销极小:
- 自旋期间线程保持运行态,避免上下文切换损耗
- 适合锁持有时间极短(比如几十纳秒)、竞争不激烈但偶发的场景
- 若自旋超阈值(如默认 10 次)仍未成功,才升级为重量级锁,真正挂起线程
怎么配合 CAS 让轻量级锁更稳
单纯靠自旋不够,JVM 还做了几层协同优化:
- 自适应自旋:JVM 根据前一次在该锁上自旋是否成功,动态调整本次自旋次数,避免空等
- 锁膨胀控制:一旦检测到同一锁频繁竞争(如连续两次自旋失败),会提前升级为重量级锁,防止无效自旋浪费 CPU
- 代码层面配合:同步块内避免耗时操作(如 I/O、sleep、复杂计算),确保锁持有时间足够短,维持轻量状态
CAS 和轻量级锁不是万能的
它们优势明显,但也有明确边界:
- 高并发、长临界区场景下,自旋会白白消耗 CPU,反而不如及时挂起更省资源
- CAS 本身不保证可见性,需搭配 volatile 或内存屏障使用(轻量级锁内部已封装处理)
- 存在 ABA 问题风险,不过轻量级锁基于对象头 Mark Word 的版本+线程 ID 组合判断,天然规避了纯数值型 ABA
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











