ReentrantReadWriteLock的实现原理

ReentrantReadWriteLock也是基于AQS来实现的,相比synchronized和ReentrantLock这种完全互斥锁。

它更加适合这种多读少写的场景。因为并发读是不会造成一个安全问题的。

那它底层是如何实现的呢?

首先依旧需要靠AQS的核心state属性,int类型的,只不过,因为我们现在有两把锁,一把读锁一把写锁,所以我们要把int拆开来用,那么在java中,int是32位的,我们将低16位用来记录写锁,高16位用来记录读锁。

写操作进来,就修改低16位的值,读操作进来就修改高16位的值。

那么由于ReentrantReadWriteLock是一个可重入锁,这个时候就会出现一个问题,我不知道哪个线程重入了。

比如ABC三个线程,但是我这里发现锁的次数是4,那么我如何找到是哪个线程重入了呢?

我们借助ThreadLoacal来解决,线程获取到锁之后,不仅要修改state,还要在自己的ThreadLocal中记录重入的次数。

那么解决了这个问题之后,我们再来看一个问题,如果我现在要写的话,那么我就需要等待读操作都执行完,此时如果读的并发非常高,一直有读操作进入,我就没法写了?这个就是写饥饿问题。

解决的方式是队列,我在读之前,先进队列找,是否有写操作在排队,如果有,那么我也进入队列排队。当写操作执行完了,那么读操作就继续飞速并发执行,直到下一个写操作的到来。相当于在写的时候我们稍微串行一下,降低了部分时间段的并发效率,保证了安全性。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值