java jvm中偏向锁的批量重偏向与批量撤销以类为单位统计,触发阈值分别为20次和40次撤销,默认参数为-xx:biasedlockingbulkrebiasthreshold=20和-xx:biasedlockingbulkrevokethreshold=40,达阈值后分别执行epoch更新重偏向或全局禁用偏向锁。

Java JVM 中偏向锁的批量重偏向与批量撤销,不是按单个对象触发,而是以 类(Class)为单位 统计并决策的。其底层触发阈值由两个 JVM 参数控制,默认值在 JDK 8–15 间保持一致:
默认阈值数值
这两个阈值在 JVM 启动时即生效,可通过 -XX:+PrintFlagsFinal 查看:
-
批量重偏向阈值:
-XX:BiasedLockingBulkRebiasThreshold=20(默认值)
当某 class 下的对象发生 20 次偏向锁撤销(即被其他线程争用导致撤销),JVM 判定该类“偏向归属频繁变更”,触发批量重偏向:提升 class 的 epoch 值,并尝试将所有已偏向该类的对象“悄悄”重新偏向到当前竞争线程。 -
批量撤销阈值:
-XX:BiasedLockingBulkRevokeThreshold=40(默认值)
若同一 class 的撤销次数累计达 40 次,JVM 认为该类已进入高频竞争场景,直接对该 class 执行批量撤销:清除所有现存偏向状态,后续新建对象也不再启用偏向锁,同步操作直接走轻量级锁逻辑。
关键细节说明
这些阈值生效需满足几个前提条件:
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- 统计对象必须属于同一个 Class;不同 class 的撤销次数互不累加。
- 撤销动作必须发生在安全点(Safepoint),因此每次撤销都伴随 STW 开销;批量操作虽减少次数,但单次开销更大。
- 阈值仅对
synchronized(obj)生效;若锁对象是obj.getClass(),则落入的是 Class 级别监视器逻辑,不参与此统计体系。 - JDK 15 起默认禁用偏向锁(
-XX:-UseBiasedLocking),所以这些阈值在新版本中实际不生效,除非显式开启。
如何验证和调整
可在启动参数中覆盖默认值,例如:
-
-XX:BiasedLockingBulkRebiasThreshold=15:提前触发重偏向,适合偏向归属切换较频繁但尚未剧烈竞争的场景。 -
-XX:BiasedLockingBulkRevokeThreshold=30:更早放弃偏向,适用于已知存在多线程争用的业务类(如共享缓存 Entry、连接池对象等)。 - 配合
-XX:+UnlockDiagnosticVMOptions -XX:+PrintBiasedLockingStatistics可输出每 class 的撤销/重偏向计数,用于线上诊断。
不复杂但容易忽略:阈值不是性能调优的“开关”,而是 JVM 对锁使用模式的自动响应信号——它反映的是代码中实际的线程访问模式,而非配置本身能改变竞争本质。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










