ReentrantReadWriterLock的ReadLock的lock方法【非公平锁实现】
2021-01-24 00:40:48 0 举报
ReentrantReadWriterLock的ReadLock的lock方法【非公平锁实现】
作者其他创作
大纲/内容
1、fullTryAcquireShare该方法内部是一个循环。2、本质上就是把上一个方法tryAcquireShared的获取读锁的逻辑拿到for循环中再判断一遍。3、因为CAS失败后,进入自旋。
doReleaseShared
更新等待队列中的头节点。把当前Node设置为头节点。
非公平锁下的读锁获取结论:1、A线程在获取读锁的情况下,如果还想去获取写锁,必须先释放读锁,再去获取写锁。会让是当前线程阻塞挂起,且永远无法被唤醒。ReadWriteLock不支持锁的升级。2、如果A线程获取读锁下,B线程去获取写锁,则B线程进入阻塞队列。然后,又有C线程去获取读锁。C线程也会进入阻塞队列。【因为非公平锁的readerShouldBlock实现。避免写线程陷入饥饿等待】
否
获取到读锁
是
线程唤醒后
最终是否获取读锁?
readerShouldBlock()
在共享模式下,当一个Node唤醒后,如果它的后继节点也是共享锁,那么就会触发『传播』。即继续唤醒它的后继节点。
lock
readerShouldBlock的非公平锁实现逻辑是:1、阻塞队列不为空,且下个节点不是共享模式,那么读线程要阻塞。2、公平锁的实现逻辑是:阻塞队列不为空,且有其它节点排队中了,则读线程要阻塞。
fullTryAcquireShared
当前读锁的数量是否超过最大限制
成功
失败
当前线程进入阻塞状态,挂起
是否已经上了写锁?
addWaiter(Node.SHARED);
加锁成功?
尝试获取锁( tryAcquireShared)
lock方法结束
tryAcquireShared
CAS修改state高16位
getExclusiveOwnerThread() == current
当前Node的前驱节点是否是头节点?
是否需要传播后继节点?
0 条评论
回复 删除
下一页