偏向锁通过“一次登记、多次免检”优化无竞争场景:首次将线程ID写入Mark Word并标记偏向状态,后续仅比对ID即可免CAS、免同步原语;其适用前提是对象长期被单一线程反复访问,一旦发生竞争即触发STW撤销,开销反超收益。

Java 中偏向锁对无竞争资源的优化,核心在于“一次登记、多次免检”——它不靠原子操作争抢,而是靠线程身份比对直接放行。
偏向锁怎么绕过同步开销
在没有其他线程竞争的前提下,偏向锁让首次获得锁的线程把自己的 ID 写入对象头的 Mark Word,并标记为“偏向状态”。之后该线程每次再进 synchronized 块时:
- 只需读取对象头,检查线程 ID 是否匹配自己
- 完全跳过 CAS(Compare-and-Swap)等原子指令
- 不触发任何 JVM 同步原语,也不涉及操作系统层面的调度干预
这比轻量级锁少了一次 CAS 操作,而 CAS 在现代 CPU 上虽快,仍需内存屏障和缓存一致性协议参与,有可观延迟。偏向锁把这部分开销降为零。
对象头如何支撑这种优化
HotSpot 对象头中的 Mark Word 在偏向锁状态下会重定义布局:
立即学习“Java免费学习笔记(深入)”;
- 54 位存储持有线程的 ID(64 位 JVM 下)
- 2 位 epoch(偏向时间戳),用于批量撤销时避免误判
- 4 位分代年龄,与 GC 协同工作
- 锁状态位保持为 01,但高位隐含“已偏向”语义
这种设计让 JVM 仅靠一次内存读取就能完成身份校验,无需写操作或锁总线,是性能提升的底层基础。
什么场景下真正生效
偏向锁不是万能加速器,只在明确符合以下特征时才带来显著收益:
- 某个对象长期被单一线程反复访问(如线程局部缓存、单例配置对象)
- 同步块执行时间短,且极少出现跨线程调用
- 应用整体锁竞争率极低(例如批处理任务、初始化阶段、日志收集器内部状态)
一旦出现第二个线程尝试获取同一把锁,JVM 就必须撤销偏向状态,升级为轻量级锁——这个撤销过程需要暂停目标线程(stop-the-world 小片段),反而带来额外开销。
要不要主动启用或禁用
从 JDK 6 到 JDK 10,默认开启偏向锁;但从 JDK 15 开始,偏向锁已被默认禁用(-XX:+UseBiasedLocking 不再生效),因为现代应用普遍呈现高并发、多线程协作特征,偏向锁的适用面大幅收窄。
- 若确认业务是典型单线程密集型(如嵌入式模块、离线工具类),可显式开启:-XX:+UseBiasedLocking
- 若压测发现大量偏向锁撤销(可通过 -XX:+PrintBiasedLockingStatistics 观察),建议关闭以规避撤销开销
- 新项目或微服务架构中,通常无需干预,默认行为已足够合理


















