为什么Spring 6中要把synchronized替换为ReentrantLock?

作为一名资深Spring爱好者,没事看看Spring的commit记录是一大爱好,这不,刚刚看了一下Spring最新的commit记录,其中有一条是这样的:

5天前提交的,标题意思是:为了避免thread pinning,所以修改了一些类中的代码,那具体修改了什么呢?我把重点给大家圈出来了:

代码中的writeLock定义为:

所以改动很明显了,就是去掉了synchronized,替换成为ReentrantLock,问题来了,为什么要这么做呢,synchronized不好用了?

我们先回到commit的标题:

我们需要解决3个问题:

1、什么是thread pinning?

2、为什么要避免thread pinning?

3、为什么把synchronized替换成ReentrantLock就可以避免thread pinning?

什么是thread pinning?

所谓thread pinning,就是线程绑定,有两种理解。

第一种,我们知道线程是在cpu上运行的,如果是多核cpu,那么同一个线程就可能一下是a核上运行,一下在b核上运行,而所谓线程绑定,就是把某一个线程固定在某个cpu核上运行。

第二种,跟虚拟线程有关,虚拟线程是JVM层面自己实现的,并不是真正的操作系统线程,并且虚拟线程是需要基于操作系统线程来运行的,因此虚拟线程和操作系统线程之间也存在绑定关系,正常情况下,一个虚拟线程可以运行在不同的操作系统线程之上,但是如果发生了thread pinning,那么就表示一个虚拟线程和一个操作系统线程绑定了,两者同生同死,那就不太好了。

而本文要分析的就是第二种情况,或者说这个commit要解决的就是第二种情况。

为什么synchronized会导致thread pinning?

当一个虚拟线程在获取锁时,如果获取不到,那么虚拟线程自身进行等待就可以了,可以把底层的操作系统线程释放掉,让它去服务其他的虚拟线程,没必要虚拟线程自己要等待,还要拉着底层操作系统线程一起等待。

但是当一个虚拟线程在执行某个加了synchronized关键字的方法时,糟糕的情况就出现了,这就会导致虚拟线程对应的底层操作系统线程要一起进行等待,从而占用了底层操作系统线程的资源,这本质上是"历史包袱",还需要给JVM底层来进行优化,因此,目前的解决方式就是使用ReentrantLock。

为什么ReentrantLock会避免thread pinning?

当一个虚拟线程在调用ReentrantLock的lock()方法进行加锁时,底层最终会调用LockSupport中的park()方法,而在这个方法中就对虚拟线程进行判断:

很明显,如果是虚拟线程就会单独进行处理,特别要注意的是,如果是虚拟线程,就不会进图中的else逻辑,也就不会对底层操作系统线程进行park,也就不会让底层操作系统线程进行等待。

VirtualThreads.park()最终会调用VirtualThread中的park():

然后调用:

然后调用:

这里似乎就是通过一个循环在进行等待?这块代码还没有深入研究,只能先这么理解了。

总之,ReentrantLock本质上就是对虚拟线程单独进行了优化,所以在加锁时,只需要虚拟线程自己等待就可以了,底层操作系统线程可以去干别的,这样就能提高底层操作系统线程的利用率。

再看一眼最开始的commit记录:

我总算知道Spring大佬为什么要避免thread pinning了,总算知道为什么要把synchronized替换成ReentrantLock了,原来是为了虚拟线程啊,赞!

我是IT周瑜,深耕Spring全家桶多年,欢迎关注我的个人公众号:IT周瑜,里面有更多干货文章。

相关推荐
思密吗喽1 分钟前
宠物商城系统
java·开发语言·vue·毕业设计·springboot·课程设计·宠物
ss27323 分钟前
019:深入解析可重入互斥锁:原理、实现与线程安全实践
java·数据库·redis
luyun02020230 分钟前
牛批了,某音录播神器
java·windows·figma
7***u21631 分钟前
显卡(Graphics Processing Unit,GPU)架构详细解读
大数据·网络·架构
高级程序源32 分钟前
springboot社区医疗中心预约挂号平台app-计算机毕业设计源码16750
java·vue.js·spring boot·mysql·spring·maven·mybatis
p***q7835 分钟前
电池管理系统(BMS)架构详细解析:原理与器件选型指南
架构
小马爱打代码37 分钟前
DDD:领域驱动设计 - 驾驭复杂业务系统的架构艺术
架构
空白诗1 小时前
mdcat 在 HarmonyOS 上的构建与适配
后端·安全·华为·rust·harmonyos
y***61311 小时前
SpringBoot集成Flowable
java·spring boot·后端