偏向锁被默认废弃并最终移除,因其依赖的“单线程长期持有”假设在多核高并发、短命对象泛滥的现代环境中失效,撤销开销大、内存成本高且阻碍JVM演进。

Java 偏向锁被默认废弃,并在高版本中逐步调整,核心原因是它原本依赖的运行假设——“单线程长期持有对象”——在现代应用环境中已严重失真,导致优化反成负担。
多核高并发让“偏向”失去前提
偏向锁设计初衷是减少无竞争场景下 CAS 的开销,适用于单线程反复访问同一对象的场景(如早期单例、线程局部缓存)。但当前服务器普遍为 32 核、64 核,微服务请求由不同线程池分发,一个 Request 对象可能刚被线程 A 偏向,几十毫秒内就被线程 B、C 轮番争抢。此时“偏向”不仅没省开销,反而成为竞争触发点。
撤销过程强制全局停顿(STW),影响延迟稳定性
只要第二个线程尝试获取已被偏向的锁,JVM 就必须执行撤销流程:
- 暂停所有 Java 线程,等待它们到达 safepoint
- 遍历目标线程栈,定位并修复锁记录
- CAS 更新对象头 Mark Word,转为轻量级锁状态
这个过程无法局部化,一次撤销就可能拉高整个应用的 P99 延迟,在高 QPS 场景下尤为明显。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
短命对象泛滥,初始化成本远超收益
WebFlux、Spring WebMvc、Quarkus 等框架大量创建短暂存活的对象(如 DTO、RequestWrapper),很多对象生命周期远小于 JVM 默认的偏向延时(4 秒)。刚被标记为“偏向”,还没来得及被第二次访问,就已被 GC 回收。而每次新建对象都要判断是否可偏向、是否在延时期、是否已禁用——这些分支判断本身就有 CPU 流水线开销。
内存与维护成本持续走高
偏向锁不是零成本:
- 每个对象头需额外预留空间存 threadID 和 epoch,64 位 JVM 下占满 62 位,增加 GC 压力
- 撤销路径比轻量级锁失败更重:涉及多次 CAS、栈帧遍历、safepoint 同步
- 逻辑深度耦合 JVM 多个子系统,阻碍同步机制持续演进和重构
JDK 15 开始默认关闭(-XX:-UseBiasedLocking),JDK 17 变为只读参数,JDK 21 彻底移除代码路径。这不是性能倒退,而是把资源投向更普适、更稳健的轻量级锁 + 自适应自旋路径。

















