ReenTranReadWriteLock 读写锁 笔记

参考博客链接:
1.https://blog.csdn.net/qq_19431333/article/details/70568478
2.https://blog.csdn.net/yanyan19880509/article/details/52435135

背景知识

继承AQS的类都需要使用state变量代表某种资源,ReentrantReadWriteLock中的state代表了读锁的数量和写锁的持有与否,整个结构如下:
可以看到state的高16位代表读锁的个数;低16位代表写锁的状态。
这里写图片描述

1.读锁的获取

public void lock() {
sync.acquireShared(1);
}
acquireShared()共享锁的实现:
1.如果当前有写线程并且本线程不是写线程,那么失败,返回-1
2. 否则,说明当前没有写线程或者本线程就是写线程(可重入),接下来判断是否应该读线程阻塞并且读锁的个数是否小于最小值,并且CAS成功使读锁+1,成功,(1.也就是说如果当前的写锁是当前线程,那么当前写锁可以再次获取读锁 或者 2.当前的是读锁状态,是当前线程的话那么读锁重入,3.不是当前线程,那么只要该获取读锁的线程的队列前没有写锁,那么该线程就可以获取读锁)返回1。其余的操作主要是用于计数的
3. 如果2中失败了,失败的原因有三,第一是应该读线程应该阻塞;第二是因为读锁达到了上线;第三是因为CAS失败,有其他线程在并发更新state,那么会调动fullTryAcquireShared方法。

2.写锁的获取(写锁可重入)

1,如果当前有写锁或者读锁。如果只有读锁,返回false,因为这时如果可以写,那么读线程得到的数据就有可能错误;如果有写锁,但是线程不同,即不符合写锁重入规则,返回false
2. 如果写锁的数量将会超过最大值65535,抛出异常;否则,写锁重入
3. 如果没有读锁或写锁的话,如果需要阻塞或者CAS失败,返回false;否则将当前线程置为获得写锁的线程(CAS成功才可以获取到写锁)

3.释放锁

  • 如果当前是写锁被占有了,只有当写锁的数据降为0时才认为释放成功;否则失败。因为只要有写锁,那么除了占有写锁的那个线程,其他线程即不可以获得读锁,也不能获得写锁
  • 如果当前是读锁被占有了,那么只有在写锁的个数为0时才认为释放成功。因为一旦有写锁,别的任何线程都不应该再获得读锁了,除了获得写锁的那个线程。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值