新三国小镇
55.33 MB · 2025-12-17
原文来自于:zha-ge.cn/java/97
啊哈,这个问题我最近还真有点感触。要不是上周项目组新同事提起“锁升级能不能降级(俗称‘退烧’)”,我还真没想到自己前几年的认知其实用词有多迷糊。说出来你别笑,Java 的 synchronized 锁升级过程,那真是比宿舍热水器的档位还复杂点。
这个故事要从一次“偶然”的 synchronized 性能调优说起。新需求来了,大家都在给某个高并发的缓存做加锁保护。理想画面里,synchronized、ReentrantLock 这些锁随用随走,锁状态自己聪明得很,锁住时候用升级,没人抢争马上退烧,“降级”,多么体贴——但事实真这样吗?
你把 synchronized 修饰的代码敲下去,JVM 内部其实要历经:
刚上手的小伙伴经常问:锁释放之后,它会不会再变回原来的更低档位?也就是重锁解掉后,会自动“退烧”到轻量级甚至无锁吗?
我的第一反应是:有道理,能省资源为啥不省?但真相就像“前任还会回来吗”这个鸡汤问题,理想很丰满,现实骨架瘦。
JVM 的 synchronized 锁升级是单向的: 偏向 → 轻量级 → 重量级 只要晋升过一次,哪怕后面没人抢,大哥级别的“重量级锁”标签就一直贴在对象头上了。
简单说,锁的升级是单行道,没有回头。
你可以这么想:
叫了警察,你觉得警察走了邻里还能回到单纯的小打小闹么?并/不/可!
其实你用 synchronized 写点抢资源的小例子,JVM 的对象头里 mark word 会这样变化:
synchronized(obj) {
// 偏向锁:仅有一个线程进来时
// 轻量级锁:多线程交替但不抢
// 重量级锁:有线程直接堵门等待
}
// 离开 synchronized 后,mark word 还会保留升级后的锁标记
现实中,你肯定也试过:
每一步我的内心都是:
直到翻了 JVM 源码(狗头),结局彻底认清了:兄弟,认命吧,没降级这回事!
来个非主流结尾鸡汤,总结几句:
最后友情推荐:
唉,感觉自己像咖啡加班后胡思乱想,边啃代码边写下这些。 锁的故事说到这,下回遇到有关 Java 内存模型、底层 sync 进阶,我再“补一嘴”!