轻量级锁通过CAS和对象头Mark Word实现用户态加锁,避免内核态切换,提升响应性能;当自旋超限或调度中断时升级为重量级锁。

轻量级锁不是用来替代重量级锁的,而是为低竞争场景“减负”:它把加锁、解锁过程留在用户态完成,避免陷入内核态做线程挂起和唤醒,从而大幅降低单次锁操作的延迟。
轻量级锁怎么实现的
核心依赖两个底层机制:对象头 Mark Word 和线程私有栈帧中的锁记录(Lock Record)。
- 线程尝试获取锁时,先在自己的栈帧里分配一块空间,作为锁记录
- 把对象当前的 Mark Word(比如无锁或偏向锁状态)拷贝进这个锁记录
- 用 CAS 指令,尝试把对象头的 Mark Word 替换为指向该锁记录的指针
- CAS 成功 → 锁获取成功,进入同步块;失败 → 说明已有其他线程在争抢,触发自旋或升级
为什么能提升响应性能
关键在于绕开了操作系统级调度开销。重量级锁一旦阻塞,就要切换到内核态、挂起线程、调度器介入、后续再唤醒——整个过程动辄毫秒级。而轻量级锁全程在用户态跑,典型耗时仅 10–100 纳秒。
- 没有线程上下文切换,CPU 缓存更友好,指令流水更连续
- 自旋等待时间短,适合临界区执行快、持有时间短的场景
- 对吞吐影响小,尤其在多核 CPU 上,多个线程可并行尝试 CAS
它什么时候会失效或升级
轻量级锁是“临时方案”,只在竞争可控时有效。一旦检测到持续争抢,JVM 就会把它升级为重量级锁。
立即学习“Java免费学习笔记(深入)”;
- 自旋次数超过阈值(如默认 10 次),继续空转不划算,就升级
- 有线程在自旋期间被系统调度走,导致自旋失去意义,也会升级
- 升级后,对象头 Mark Word 被设为指向 ObjectMonitor 的指针,进入操作系统互斥逻辑
实际使用中要注意什么
它不是“开箱即用”的银弹,效果高度依赖代码模式和运行环境。
- 临界区代码必须足够轻——比如只是更新一个计数器,而不是调用远程接口或 IO 操作
- 避免在单核 CPU 或高负载环境下过度依赖自旋,容易浪费 CPU
- JDK 15+ 默认关闭偏向锁,轻量级锁成为无竞争→轻度竞争阶段的主要过渡形态
- 可通过 -XX:+PrintAssembly 查看 synchronized 编译后的锁膨胀过程,辅助性能分析



















