锁升级到底能不能“退烧”?synchronized 释放后状态解析

原文来自于:https://zha-ge.cn/java/97

锁升级到底能不能“退烧”?synchronized 释放后状态解析

啊哈,这个问题我最近还真有点感触。要不是上周项目组新同事提起“锁升级能不能降级(俗称‘退烧’)”,我还真没想到自己前几年的认知其实用词有多迷糊。说出来你别笑,Java 的 synchronized 锁升级过程,那真是比宿舍热水器的档位还复杂点。

偶遇 synchronized的小心思

这个故事要从一次“偶然”的 synchronized 性能调优说起。新需求来了,大家都在给某个高并发的缓存做加锁保护。理想画面里,synchronized、ReentrantLock 这些锁随用随走,锁状态自己聪明得很,锁住时候用升级,没人抢争马上退烧,“降级”,多么体贴——但事实真这样吗?

你把 synchronized 修饰的代码敲下去,JVM 内部其实要历经:

  • 无锁
  • 偏向锁
  • 轻量级锁
  • 重量级锁(就是 OS 层的粗大锁啦)

刚上手的小伙伴经常问:锁释放之后,它会不会再变回原来的更低档位?也就是重锁解掉后,会自动“退烧”到轻量级甚至无锁吗?

我的第一反应是:有道理,能省资源为啥不省?但真相就像“前任还会回来吗”这个鸡汤问题,理想很丰满,现实骨架瘦。

懂点原理,别和 JVM 抬杠

JVM 的 synchronized 锁升级是单向的: 偏向 → 轻量级 → 重量级 只要晋升过一次,哪怕后面没人抢,大哥级别的“重量级锁”标签就一直贴在对象头上了。

简单说,锁的升级是单行道,没有回头

你可以这么想:

  • 偏向锁就像一个偷偷摸摸的小偷,只有主人自己拿,不闹事。
  • 轻量级锁像邻里借钥匙,大家排队还配合。
  • 重量级锁,哎呀,一旦街坊们起冲突得叫警察,大家都得耐心排大队。

叫了警察,你觉得警察走了邻里还能回到单纯的小打小闹么?并/不/可!

关键代码来了

其实你用 synchronized 写点抢资源的小例子,JVM 的对象头里 mark word 会这样变化:

synchronized(obj) {
    // 偏向锁:仅有一个线程进来时
    // 轻量级锁:多线程交替但不抢
    // 重量级锁:有线程直接堵门等待
}
// 离开 synchronized 后,mark word 还会保留升级后的锁标记

踩坑瞬间

现实中,你肯定也试过:

  • 我用 synchronized 配合几百个线程压力测,想验证下锁会不会自行降级。
  • 线程走完 synchronized 段后,obj 还能否回到轻松状态?
  • 我甚至 debug mark word 的内容,发现——锁升级后,结束 synchronized,那个“重量级锁”的痕迹一直搁那儿。

每一步我的内心都是:

  • “不会吧,JVM 真懒得省资源?”
  • “对象头不会‘自我修复’下吗?”
  • “锁降级要是不支持,太浪费了……”

直到翻了 JVM 源码(狗头),结局彻底认清了:兄弟,认命吧,没降级这回事!

经验启示

来个非主流结尾鸡汤,总结几句:

  • synchronized 的锁升级只有升级没有降级,“退烧”下线。
  • 尽量避免在高并发下靠 synchronized 抢重锁,能用更轻快的锁(比如 CAS、LongAdder)就优先用。
  • 重锁后的对象,哪怕一阵子没人用,也仍然背着“警察到过”的包袱。
  • 真想“复健”,用锁分片、对象池化、线程局部变量等办法去规避。

最后友情推荐:

  • 不要乱造锁升级降级的“性能幻想”,JVM 还是那个JVM。
  • 多关注 Java Object Layout 工具,mark word 内容和锁状态一清二楚,避免拍大腿瞎猜。

唉,感觉自己像咖啡加班后胡思乱想,边啃代码边写下这些。 锁的故事说到这,下回遇到有关 Java 内存模型、底层 sync 进阶,我再“补一嘴”!

优秀的个人博客,低调大师

微信关注我们

转载内容版权归作者及来源网站所有!本站原创内容转载请注明来源!

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

相关文章

发表评论

资源下载

更多资源
Oracle Database,又名Oracle RDBMS

Oracle Database,又名Oracle RDBMS

Oracle Database,又名Oracle RDBMS,或简称Oracle。是甲骨文公司的一款关系数据库管理系统。它是在数据库领域一直处于领先地位的产品。可以说Oracle数据库系统是目前世界上流行的关系数据库管理系统,系统可移植性好、使用方便、功能强,适用于各类大、中、小、微机环境。它是一种高效率、可靠性好的、适应高吞吐量的数据库方案。

Apache Tomcat7、8、9(Java Web服务器)

Apache Tomcat7、8、9(Java Web服务器)

Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache、Sun 和其他一些公司及个人共同开发而成。因为Tomcat 技术先进、性能稳定,而且免费,因而深受Java 爱好者的喜爱并得到了部分软件开发商的认可,成为目前比较流行的Web 应用服务器。

Eclipse(集成开发环境)

Eclipse(集成开发环境)

Eclipse 是一个开放源代码的、基于Java的可扩展开发平台。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。幸运的是,Eclipse 附带了一个标准的插件集,包括Java开发工具(Java Development Kit,JDK)。

Sublime Text 一个代码编辑器

Sublime Text 一个代码编辑器

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。