文章40 | 阅读 14787 | 点赞0
ReentrantReadWriteLock中利用state的前16位表示读锁、后16位表示写锁
而下面图片源码如果出现w
就代表写锁的个数,r
是读锁的个数
写锁加锁失败的情况
下面的方法是尝试加写锁时会执行的方法,判断的方法如下
public final void acquire(int arg) {
if (!tryAcquire(arg)) { // 尝试加锁,失败则需要进入队列
acquire(null, arg, false, false, false, 0L);
}
}
判断中的方法如下
c!=0
说明加过锁,如果接着w==0
就会直接返回false
。这种情况就是说明加的全是读锁。
对应着读写
操作
因此上面的if代码块内的方法会被执行,也就是会将当前获取写锁的线程加入阻塞队列中去。
这种好理解对应写写
操作,也就是c!=0、可 w!=0 但 current != getExclusiveOwnerThread()成立
写锁加锁成功的情况
也就是对应着c=0
这种情况,会直接到后面,最终返回true
要想不执行return false
就必须或两边都是false,也就是要w!=0
且当前线程=持有写锁的线程
,相当于写锁重入,然后更新state中的写锁个数
读锁加锁成功的情况
public final void acquireShared(int arg) {
if (tryAcquireShared(arg) < 0) // 尝试获取读锁,失败则需要将节点加入aqs队列
acquire(null, arg, true, false, false, 0L);
}
持有写锁的线程拥有最高权限,自然再加读锁是没有关系的。
有一种情况比较特殊,如果读锁设置为排他的,那么会导致执行方法最后以一行的return 传入线程。
目的尝试排他读的抢占读锁是成功,失败也会进入队列。
读排他似乎我没看到ReentrantReadWriteLock对读锁的定义,虽然设计了,但似乎没有这种情况(如果有误望指正
)。
读锁加锁失败的情况
对应着写读
状态,exclusiveCount(c) != 0
说明已经加过写锁,并且当前线程不是这个写锁的持有者线程。
讲道理的方式理解:如果当前线程是持有写锁的那个线程,自然抢占读锁自然没问题,因为持有写锁就相当于独占(想怎么写、想怎么读都随便)
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://yumbo.blog.csdn.net/article/details/110104745
内容来源于网络,如有侵权,请联系作者删除!