偏向锁本身不支持主动“重新分配”,所谓重分配实为JVM自动触发的撤销+重偏向或升级组合动作:单次竞争触发安全点撤销;达20次撤销启动批量重偏向(静默换主);达40次则批量撤销并禁用该类偏向锁。

Java 偏向锁本身不支持“重新分配”线程,它没有主动移交、转让或再偏向的语义。所谓“重新分配”,实际是 JVM 在检测到竞争后,通过撤销(revocation)+ 重偏向(rebias)或升级(upgrade) 这一组合动作,间接实现锁归属的变更。整个过程完全由 JVM 自动控制,不依赖线程主动释放,也不允许用户干预。
下面从三个关键环节讲清楚这个机制如何运作:
偏向锁撤销:竞争触发的强制清理
当线程 B 尝试进入一个已被线程 A 偏向的对象的 synchronized 块时:
- JVM 检查对象头 Mark Word,发现偏向线程 ID 是 A,不是 B;
- 立即标记该锁“需撤销”,但不立刻执行;
- 等待所有线程运行至安全点(safepoint),暂停线程 A;
- 在 safepoint 内检查线程 A 是否仍在同步块中:
- 若已退出 → 直接将对象头恢复为无锁状态(标志位
01,线程 ID 清空); - 若仍在执行 → 升级为轻量级锁(标志位
00,写入指向线程 A 栈中锁记录的指针)。
- 若已退出 → 直接将对象头恢复为无锁状态(标志位
注意:撤销不是“把锁还给 B”,而是清除 A 的偏向状态,为后续加锁铺路。
立即学习“Java免费学习笔记(深入)”;
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
轻量级锁竞争:B 线程真正获取锁的机会
撤销完成后,对象处于:
- 无锁状态(A 已退出)→ 线程 B 可直接尝试 CAS 获取偏向锁(若仍启用);
- 轻量级锁状态(A 仍在临界区)→ 线程 B 执行标准轻量级锁流程:在自己栈帧中新建 Lock Record,CAS 替换 Mark Word;
- 若 CAS 成功,B 成为新持有者;失败则可能自旋或膨胀为重量级锁。
此时,B 并非“继承”了 A 的偏向权,而是以轻量级方式重新竞争获得锁。
批量重偏向:对同类新对象跳过撤销步骤
如果同一类(如 ArrayList)的多个对象频繁被线程 A 偏向、又被线程 B 竞争撤销(达默认 20 次),JVM 会启动批量重偏向:
- 后续新创建的该类对象,不再默认偏向线程 A;
- 而是直接用 CAS 将对象头设为偏向当前请求线程(比如 B);
- 这样 B 第一次访问新对象时,无需触发撤销,直接走偏向路径。
这看起来像“重新分配”,实则是 JVM 基于统计预测,提前把偏向权授予更活跃的线程。
不复杂但容易忽略

















