Java中的锁升级机制:偏向锁、轻量级锁和重量级锁

发布于 2024-07-18
713

我们非常重视原创文章,为尊重知识产权并避免潜在的版权问题,我们在此提供文章的摘要供您初步了解。如果您想要查阅更为详尽的内容,访问作者的公众号页面获取完整文章。

扫码阅读
手机扫码阅读
Java中的锁升级机制:偏向锁、轻量级锁和重量级锁

Java中的锁升级机制:偏向锁、轻量级锁和重量级锁

Monitor实现的锁属于重量级锁,你了解过锁升级吗?

随着JDK版本的升级,Java的synchronized关键字在性能上进行了优化,打破了“性能很差”的谣言。锁机制根据竞争情况分为无锁、偏向锁、轻量级锁和重量级锁四种状态。

重量级锁

重量级锁由Monitor实现,涉及用户态与内核态的切换以及上下文转换。这种机制在多线程竞争下性能较低,开销较大。JDK 1.6引入了偏向锁和轻量级锁,以优化无竞争或低竞争场景下的性能表现。

MarkWord

Java对象在内存中的布局包含对象头,其中的MarkWord用于存储锁状态。根据MarkWord的后三位或后两位标识,可以区分对象当前的锁状态:

  • 001:无锁
  • 101:偏向锁
  • 00:轻量级锁
  • 10:重量级锁

轻量级锁

轻量级锁适用于无竞争的同步块场景,通过CAS操作实现加锁和解锁,避免了重量级锁的上下文切换开销。在竞争激烈时,轻量级锁会升级为重量级锁。

加锁流程

  1. 在线程栈中创建Lock Record,并指向锁对象。
  2. 通过CAS修改MarkWord,标记为轻量级锁。
  3. 支持锁重入,利用Lock Record记录重入次数。
  4. CAS失败则升级为重量级锁。

解锁流程

  1. 遍历线程栈,找到对应Lock Record。
  2. 处理Lock Record的重入情况。
  3. 通过CAS恢复无锁状态,CAS失败则升级为重量级锁。

偏向锁

偏向锁适用于长时间只被一个线程持有的场景。第一次使用CAS操作设置线程ID,之后无需CAS,只需判断MarkWord中的线程ID是否一致,从而进一步提升性能。

偏向锁升级

  1. 在线程栈创建Lock Record并指向锁对象。
  2. 通过CAS设置线程ID及偏向锁标识。
  3. 支持重入,但不再进行CAS操作,仅判断线程ID。
  4. 多线程竞争时,偏向锁会升级为轻量级或重量级锁。

总结

Java的synchronized关键字通过锁升级机制优化了多线程竞争场景,提升了性能。

  • 重量级锁:适用于多线程竞争,性能较低。
  • 轻量级锁:无竞争时使用CAS优化性能。
  • 偏向锁:长时间单线程持有锁时进一步优化。

如果您觉得本文内容有帮助,欢迎分享、点赞和收藏!

springboot葵花宝典

主要分享JAVA技术,主要包含SpringBoot、SpingCloud、Docker、中间件等技术,以及Github开源项目

272 篇文章
浏览 231.5K

还在用多套工具管项目?

一个平台搞定产品、项目、质量与效能,告别整合之苦,实现全流程闭环。

加入社区微信群
与行业大咖零距离交流学习
PMO实践白皮书
白皮书上线