批量重偏向与批量撤销是HotSpot JVM针对偏向锁在多线程场景下性能退化的自适应优化机制:前者在满足阈值条件时直接将某类新对象的偏向线程ID设为高频访问线程,跳过撤销再偏向流程;后者在该类撤销次数超限时于安全点全局禁用其偏向锁,使后续对象以无锁状态开始。

Java 中 synchronized 的批量重偏向(Bulk Rebias)与批量撤销(Bulk Revoke)是 HotSpot JVM 针对偏向锁在多线程场景下性能退化问题设计的自适应优化机制。它们不改变单个对象的锁行为,而是基于类级别统计信息,在安全点统一调整一批对象的锁状态,从而避免高频、重复的锁状态切换开销。
批量重偏向:跳过“撤销再偏向”的三步操作
当某个类的大量新对象最初被线程 A 偏向,随后线程 B 频繁对其加锁并触发偏向撤销(升级为轻量级锁),JVM 会识别这种模式,并在满足条件时直接将该类后续新建对象的偏向线程 ID 设为线程 B。
- 触发条件包括:该类对象被撤销次数达到 -XX:BiasedLockingBulkRebiasThreshold(默认 20 次),且距上次批量操作已过 -XX:BiasedLockingDecayTime(默认 25 秒)
- 仅影响该类**新分配的对象**,已存在的对象保持原状态(除非显式触发竞争或调用
hashCode()) - 本质是一种预测性优化——用一次类级别设置,替代数十次对象级 CAS 和撤销流程
批量撤销:全局禁用某类的偏向锁
当一个类的对象频繁遭遇真实竞争(多个线程交替获取锁),导致大量偏向锁被撤销并升级,JVM 判定该类不再适合使用偏向锁,于是执行批量撤销。
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 判断依据是:该类对象撤销次数在短时间内(如 25 秒内)超过 -XX:BiasedLockingBulkRevokeThreshold(默认 40 次)
- 动作发生在安全点,所有 Java 线程暂停;JVM 清除该类所有已存在对象的偏向标志,并将类标记为“不可偏向”
- 此后该类新建对象默认以无锁状态开始,不再进入偏向锁流程
关键参数与运行控制
这两个机制完全由 JVM 自动管理,但可通过启动参数调整行为边界:
立即学习“Java免费学习笔记(深入)”;
- -XX:BiasedLockingBulkRebiasThreshold=20:控制批量重偏向阈值,调低可更早启用预测性偏向
- -XX:BiasedLockingBulkRevokeThreshold=40:控制批量撤销阈值,调高可延缓禁用偏向锁
- -XX:BiasedLockingDecayTime=25000:决定撤销计数衰减周期,避免历史数据长期干扰判断
- -XX:+PrintBiasedLockingStatistics:启用后可在 GC 日志中查看各类撤销/重偏向统计
为什么需要这两者?
偏向锁本意是优化单线程场景,但在实际应用中常出现“先由线程 A 初始化,再由线程 B 主导访问”的模式。若每次加锁都走“偏向→撤销→轻量级锁→(可能)重偏向”,会造成大量无谓的 CAS 和 safepoint 开销。批量机制把分散的操作聚合成一次类级别决策,既保留了偏向锁在低竞争下的优势,又避免其在中等竞争下成为性能瓶颈。

















