偏向锁在多线程交替执行时性能更差。因其设计假设单线程反复访问,一旦出现线程切换就会频繁触发撤销(需安全点停顿、遍历栈、重置mark word)和锁升级,反而增加开销;jdk15起已默认禁用。

偏向锁在多线程交替执行时表现不佳,甚至会成为性能负担。
偏向锁的设计初衷就是避免竞争
它假设:同一个对象的同步块几乎总是由同一线程反复进入。一旦检测到其他线程尝试获取该锁,JVM就会立即撤销偏向状态,触发锁升级(偏向锁 → 轻量级锁),这个过程本身就有开销:
- 需要暂停持有偏向锁的线程(safe point 检查)
- 遍历该线程栈,查找并修正所有指向该对象的锁记录
- 将对象头 Mark Word 重置为无锁或轻量级锁状态
交替执行会频繁触发撤销和升级
当两个或多个线程轮流获取同一把锁(比如生产者-消费者模型中频繁切换访问队列),每次切换都相当于一次“竞争事件”:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- 线程 A 持有偏向锁 → 线程 B 尝试进入 → 触发撤销 → 升级为轻量级锁
- 线程 B 获取轻量级锁 → 线程 A 再次尝试 → 自旋失败后可能升级为重量级锁,或反复自旋
- 这种来回切换会让偏向锁不仅失去优化价值,反而因频繁撤销带来额外 GC 压力和 safepoint 停顿
实际场景中建议关闭偏向锁
对于明确存在线程交替访问的业务逻辑(如 Netty 的 event loop 切换、RPC 请求分发、缓存读写分离等),可通过 JVM 参数禁用偏向锁:
- -XX:-UseBiasedLocking:彻底关闭偏向锁机制
- 搭配 -XX:BiasedLockingStartupDelay=0(若需调试)仅用于观察初始状态,不解决交替问题
- 现代 JDK(如 JDK 15+)已默认禁用偏向锁,部分版本甚至移除了相关代码
替代方案更适配交替场景
当锁被多个线程轮番使用时,轻量级锁(CAS + 自旋)或 ReentrantLock 配合公平策略通常更稳定:
- 轻量级锁避免了内核态切换,适合短临界区、低频竞争
- ReentrantLock 可显式控制公平性,减少线程饥饿,更适合可预测的交替模式
- 无锁结构(如 ConcurrentLinkedQueue、LongAdder)在高并发交替读写中往往吞吐更高
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










