偏向锁在多线程竞争时被被动撤销,而非主动释放;撤销由竞争线程触发,需等待安全点,检查持有线程是否仍在同步块内:若已退出则恢复无锁状态,否则升级为轻量级锁。

偏向锁在多线程竞争时不会“自动释放”,而是被被动撤销——这个过程不是由持有线程主动退出触发的,而是由另一个线程尝试获取锁时,JVM检测到竞争后立即启动的强制清理操作。
撤销发生的准确时机
只要另一个线程进入 synchronized 块并发现对象头中记录的偏向线程 ID 与自己不匹配,撤销就已触发。注意:
- 不要求竞争线程成功获取锁,哪怕 CAS 失败也照样触发撤销;
- 撤销不是立刻执行,必须等待所有线程运行到安全点(safepoint)才能开始;
- 即使持有线程早已退出同步块,JVM 仍需在 safepoint 挂起它、检查栈帧,再完成撤销。
撤销过程的关键步骤
撤销不是简单清空线程 ID,而是一次带状态迁移的原子操作:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 定位持有线程:通过对象头中的线程 ID 找到对应 Java 线程;
- 检查同步状态:遍历该线程栈帧,确认它是否仍在执行原同步块;
- 两种路径分支:
- 若已退出 → 将对象头恢复为无锁状态(标志位
01); - 若仍在执行 → 升级为轻量级锁(标志位
00,写入指向栈中锁记录的指针);
- 若已退出 → 将对象头恢复为无锁状态(标志位
- 对象头更新完成后,后续加锁直接走轻量级锁逻辑(CAS + 自旋)。
批量撤销与阈值控制
单次撤销开销小,但高频竞争会引发大量 safepoint 停顿。JVM 为此引入批量机制:
- 同一类对象的偏向锁被撤销达 40 次(默认值
BiasedLockingBulkRevokeThreshold=40),JVM 会禁用该类所有新实例的偏向锁; - 此时现存已偏向对象会被批量撤销,新对象创建即为无锁或轻量级锁状态;
- 该机制不可逆,除非重启 JVM 或显式重置类元数据(如使用
-XX:BiasedLockingStartupDelay=0并配合类卸载)。
哪些操作会强制触发撤销
除线程竞争外,以下行为也会导致偏向锁失效:
- 调用对象的
hashCode():会覆盖 Mark Word 中的线程 ID 字段; - 调用
wait()/notify():必须升级为重量级锁,连带撤销偏向状态; - 显式关闭偏向锁:
-XX:-UseBiasedLocking(JDK 15+ 默认关闭)。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










