轻量级锁是synchronized在无/低竞争下的优化机制,依赖cas原子修改mark word(v为当前值、a为期望无锁态、b为指向lock record的指针),失败则自旋重试,自旋超阈值后升级为重量级锁。

轻量级锁是 Java 中 synchronized 在无竞争或低竞争场景下的优化机制,核心依赖 CAS(Compare-And-Swap)和自旋,不立即陷入操作系统内核态,从而避免重量级锁的线程挂起/唤醒开销。
CAS 是轻量级锁的原子操作基础
CAS 在轻量级锁中用于安全修改对象头中的 Mark Word。它有三个关键要素:
- V(内存值):对象头中当前的 Mark Word 值
- A(预期值):线程期望该位置仍为“未加锁”状态(如指向 klass 指针)
- B(新值):线程准备写入的“指向本线程 Lock Record 的指针”
只有当 V == A 时,JVM 才原子地将 Mark Word 替换为 B;否则失败,说明已有其他线程抢先加锁。
自旋是轻量级锁的竞争应对策略
当线程尝试加锁失败(CAS 不成功),并不马上阻塞,而是进入有限次数的循环重试(默认约 10 次,JVM 可自适应调整):
- 每次重试前重新读取 Mark Word,判断是否已释放、是否被自己持有(支持重入)、或是否已膨胀为重量级锁
- 若发现是自己持有的锁,就新建一个 Lock Record 计数器,完成重入逻辑
- 若发现是别的线程持有且未升级,则继续自旋等待
锁膨胀是自旋失败后的自然升级
自旋不是无限进行的。当达到阈值或竞争持续存在,JVM 就触发锁膨胀:
- 向操作系统申请 Monitor 对象
- 把对象头 Mark Word 改为指向该 Monitor 的指针
- 原持有线程成为 Owner,竞争线程进入 Monitor 的 EntryList 并转为 BLOCKED 状态
此时轻量级锁已退出,后续所有对该对象的同步操作都走重量级锁路径。
为什么说它是“轻量”的?
因为它全程在用户态完成,不涉及:
- 系统调用(如 pthread_mutex_lock)
- 线程状态切换(RUNNABLE ↔ BLOCKED)
- 内核调度器介入
只要竞争不激烈、持有时间短,CAS + 自旋就能以极小代价维持同步语义。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











