前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >reentrantLock 和 synchronized 哪个性能高?

reentrantLock 和 synchronized 哪个性能高?

作者头像
好好学java
发布2020-03-20 10:50:11
1.1K0
发布2020-03-20 10:50:11
举报
代码语言:javascript
复制
链接:https://segmentfault.com/a/1190000022041809

synchronized 底层实现由jvm 保证,

在jvm 运行过程中,可能出现 偏向锁,轻量级锁,重量级锁 (锁的重量依次加重)

偏向锁 实现是在 先确认偏向锁标识是可获得状态,第一次获取到锁的时候,将对象的 mark word 中的偏向锁线程的标识为自己,下一次进入到同步块的时候,直接获取锁。当有其他线程竞争锁的时候,发现 markword 并不是自己,会尝试进行一次 cas 替换,如果不成功,就会将锁升级为轻量级锁 消耗:极少

轻量级锁 实现:在执行同步块之前,jvm 会先在当前线程的栈帧中创建用于存储所锁记录的空间,并将对象头中 markWord 复制到锁记录中,。然后线程尝试使用 cas 将对象头中的 mark word 替换为指向锁记录的指针,如果成功,当前线程获得锁,如果失败,说明以有竞争,当前线程会使用自旋来获取锁。自旋获取锁失败,会将对象头的锁标识改为重量级指针。解锁的时候,会使用原子 Cas 操作将 Displaced Mark Word 替换为对象头,成功说明没有发生竞争, 如果失败,说明当前锁存在竞争,锁会膨胀为重量级锁。

消耗:复制和自旋

重量级锁:

Synchronized是通过对象内部的一个叫做监视器锁(monitor)来实现的。但是监视器锁本质又是依赖于底层的操作系统的Mutex Lock来实现的。而操作系统实现线程之间的切换这就需要从用户态转换到核心态,这个成本非常高,状态之间的转换需要相对比较长的时间,这就是为什么Synchronized效率低的原因。因此,这种依赖于操作系统Mutex Lock所实现的锁我们称之为“重量级锁”。JDK中对Synchronized做的种种优化,其核心都是为了减少这种重量级锁的使用。JDK1.6以后,为了减少获得锁和释放锁所带来的性能消耗,提高性能,引入了“轻量级锁”和“偏向锁”。

reentrantLock 的实现:

reentrantLock基于 AQS 实现。AQS 内部通过对 volatile 的 state 读写以及cas 操作 和在某些条件下让线程进入阻塞状态实现。

volatile 消耗小于 synchronized ,reentrantLock 中某些条件下让线程进入阻塞状态 的消耗 可能与 synchronized 相当。

因此 性能 偏向锁 > 轻量级锁 > reentrantLock > synchronized

而偏向锁 和轻量级锁 能够启用是在特殊条件下的。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-03-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 好好学java 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档