偏向锁本身不适用于高并发场景,其设计目标是单线程反复访问、几乎无竞争的场景;强行用于高并发会因频繁撤销和升级反增开销,需禁用并配合轻量级锁、减小粒度等策略协同优化。

偏向锁在高并发场景下**本身不适用**,它的设计目标恰恰是“避开高并发”——专为单线程反复访问、几乎无竞争的场景而生。把它强行用在高并发环境,不仅不能优化性能,反而会因频繁撤销和升级带来额外开销。真正有效的做法,是理解它的边界,并配合其他策略协同优化。
明确偏向锁的适用前提
偏向锁生效需要同时满足三个条件:
- 对象未调用过 hashCode():一旦调用,Mark Word 被写入哈希值,无法再存储线程 ID,偏向锁直接失效
- JVM 启动时未禁用偏向锁(默认开启,可通过 -XX:-UseBiasedLocking 关闭)
- 锁对象在初始化后,首次获取由同一个线程完成,且后续长期由该线程独占:例如 Spring 单例 Bean 的初始化方法、ThreadLocal 初始化块、配置类加载逻辑
高并发中避免偏向锁“反向拖累”
当多个线程快速争用一个本该偏向的对象时,JVM 需要执行“偏向撤销”——暂停所有线程(safepoint)、遍历栈帧确认锁状态、批量重置 Mark Word。这个过程代价很高。应对方式包括:
- 对高频共享对象主动禁用偏向锁:比如全局计数器、缓存锁对象、连接池中的连接对象,启动参数加 -XX:-UseBiasedLocking
- 避免在锁对象上调用 hashCode():若业务逻辑确实需要哈希(如放入 HashMap),优先使用其他标识字段,或改用不依赖对象头哈希的实现
- 用轻量级锁更合适的场景,就别强求偏向:例如 Web 请求中每个线程操作各自 Session 对象,天然隔离,偏向有效;但若多个请求共用同一把“全局配置锁”,就该换锁粒度或锁类型
配合其他锁优化形成组合策略
偏向锁只是 JVM 锁优化的第一环。在真实高并发系统中,需与以下手段协同使用:
立即学习“Java免费学习笔记(深入)”;
- 减小锁粒度:把一个大锁拆成多个小锁(如 ConcurrentHashMap 分段锁),让不同线程操作不同数据段,降低竞争概率,提高偏向锁/轻量级锁命中率
- 缩短锁持有时间:把耗时操作(IO、计算)移出 synchronized 块,只保护真正共享变量的读写,减少其他线程自旋或阻塞等待时间
- 读写分离:读多写少场景下,用 ReentrantReadWriteLock 替代 synchronized,让读操作完全无锁化,并发吞吐显著提升
- 无锁替代:对简单计数、状态标记等,优先使用 AtomicLong、LongAdder、CAS 操作,彻底绕过锁机制
验证与调优建议
不要凭经验猜测锁行为,用工具实测:
- 添加 JVM 参数 -XX:+PrintSynchronizationStatistics -XX:+UnlockDiagnosticVMOptions 查看锁升级统计
- 用 JFR(Java Flight Recorder)或 JMC 抓取锁竞争热点,定位哪些对象频繁升级到重量级锁
- 对比开启/关闭偏向锁时的 QPS 和 GC pause,尤其关注 safepoint 停顿次数是否激增



















