偏向锁撤销成本高,核心在于必须触发全局安全点暂停所有线程以协调修改对象头和栈帧状态,哪怕单个对象撤销也可能引发毫秒级STW;频繁撤销会触发类级别批量禁用(阈值20次),且其开销本质是JVM系统级协同成本而非单纯位操作。

偏向锁撤销成本高,核心在于它不是一次简单的位修改,而是牵涉 JVM 全局协调的重量级操作。
必须停顿所有线程才能撤销
当第二个线程尝试获取一个已偏向的对象时,JVM 不能直接改 Mark Word。因为原偏向线程可能正在执行同步块,其栈帧里隐含依赖当前偏向状态(比如重入时跳过 CAS)。此时 JVM 必须:
- 触发全局安全点(Safepoint),暂停所有 Java 线程
- 等待原偏向线程运行到安全点位置(如方法返回、循环边界)
- 检查该线程是否仍在持有锁、是否已退出临界区
- 确认后,才把 Mark Word 恢复为无锁或升级为轻量级锁
哪怕只撤销一个对象的偏向锁,也可能带来一次毫秒级的 STW(stop-the-world)停顿。
撤销失败会引发类级别策略退化
如果某类对象频繁发生撤销(例如 ConcurrentHashMap 的 Node 实例),JVM 会统计撤销次数。默认阈值是 20 次:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
立即学习“Java免费学习笔记(深入)”;
- 超过后,对该类所有新创建的实例批量禁用偏向锁
- 后续该类对象一出生就是无锁状态,跳过偏向阶段
- 这相当于用整个类的优化潜力,为单个对象的撤销代价买单
对比轻量级锁:原子性 vs 协调性
轻量级锁加锁/解锁都靠单次 CAS 完成,全程在用户态,无 Safepoint 依赖。而偏向锁撤销:
- 没有 CPU 指令能“悄悄覆盖”一个被线程信任的状态
- 必须靠 JVM 运行时协同调度——暂停、检查、恢复
- 本质是一次微型 GC 式开销,不是锁本身的位操作成本,而是系统级协调成本
启动期延迟开启也是为规避撤销成本
JVM 默认在启动后 4 秒才启用偏向锁,原因很实际:
- 启动阶段大量类加载、静态初始化会用到 synchronized
- 若此时就启用偏向锁,极易因多线程竞争触发密集撤销
- 延迟是为了让系统稳定后再进入偏向锁适用场景,避开高撤销风险期

















