高并发读锁StampedLock,你值得拥有

人的一生就像在攀登高峰,勤奋是你踏实稳健的双脚,信念是你指引前行的向导,勇敢是你孜孜追寻的恒心。开心日到了,愿你站稳双脚,确定方向,向着你的理想巅峰勇敢前行,不用怕,未来就在你的脚下。

作为一名面试官,我在面试别人的时候,经常反复拿来问别人的一个问题,最近详细整理了一下,跟大家分享一下。总结的不好的地方或者有不同见解的地方欢迎大家私聊我一起探讨。

 

1. 为什么引入StampedLock

JDK8中新增StampedLock。

从ReentrantLock到ReentrantReadWriteLock,再到StampedLock,读操作并发度依次提高。

ReentrantReadWriteLock采用“悲观读”策略,当第一个读线程抢到共享锁,第二个、第三个读线程还可以抢到共享锁,使得写线程一直无法获取互斥写锁,会导致写线程“饿死”。

读写锁的公平/非公平实现中,尽量避免这种情形,但还有可能发生

StampedLock通过读写不互斥进一步提高读的并发量。

读写不互斥的问题在于:会产生不可重复读,两次读取结果不一样。

即读取的时候,可能另一个线程正在修改该值,还没有完成,读完之后,写线程也操作结束,此时读线程读到的数据和真实的数据不一致。

2. StampedLock的解决方式

StampedLock引入了“乐观读”策略:

  • 读的时候不加读锁,读出来发现数据被修改了,再升级为“悲观读”;即读错了再严格读一次,避免写线程被饿死。
  • StampedLock是一个读写锁,悲观读和悲观写的锁状态需要同步,互斥,锁状态操作需要是原子操作。

首先需要在state中划分出读锁和写锁。

 

3. state中的具体表示

state用于表示锁状态:

private transient volatile long state;

 

第1-7位记录共享锁读锁,每获取一个读锁,该7位+1,如果溢出,每溢出一次,readerOverflow+1;

每释放一个读锁,该值-1,如果不够,借位readerOverflow的值。

第8位记录互斥锁写锁状态,如果存在写锁,该位记1,不存在记0;

第8-64位用于记录乐观锁版本号。

每获取一次写锁,state+WBIT,即从第8位开始的值。释放写锁,并不让state-WBIT,保证乐观锁版本号的单调递增,防止乐观锁出现ABA问题,即在tryOptimisticReadvalidate(stamp)之间获取写锁并释放写锁。

如果从第8位到第64位都是1,则再加WBIT,将导致state是0,因为64位越界,此时将state复位ORIGIN:

即:

获取写锁的时候,state+WBIT,释放的时候state+WBIT,第一次让写锁位置位1,第二次让写锁位置位0,同时乐观锁位表示的值增大。

当写锁位是1的时候,悲观读锁位都是0,readerOverflow也是0。

当写锁位是0的时候,如果悲观锁抢锁,则写锁位的7位以及readerOverflow用于记录cowait链表获取共享读锁的状态。

 

4. StampedLock流程

4.1 tryOptimisticRead方法

先判断是否存在写锁,如果存在,就返回0L,表示乐观锁获取失败。

如果不存在写锁,就获取此时的乐观锁版本号,以用于稍后的validate(stamp)校验乐观锁的成功与否。

 

4.2 悲观读锁以及StampedLock实现的CLH队列

WMODE是互斥锁,链表中是单节点,RMODE是共享读锁,使用cowait进行横链连接同是RMODE的节点。

 

 

最近收集整理一些面试资料,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等技术点,有兴趣的同学可以+VX(lagou2021) 获取相关资料

 

福利

海量互联网大厂面试真题详解与大家分享,共同学习。 职业规划、简历指导、Java实用书籍、各种Java学习视频、技能的学习、思维的培养。 感兴趣的小伙伴可以关注一下我的CSDN账号,私聊获取个类资料。(或者微信账号:lagou2021)

附赠1: 10G开发相关电子书,总有一款适合你,私聊获取

图片.png

图片.png

附赠2:成功入职大厂60k的简历模板,私聊获取

图片.png

                          

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值