ReentrantReadWriteLock jdk17
2024-04-06 20:50:17 0 举报
ReentrantReadWriteLock jdk17
作者其他创作
大纲/内容
尝试失败
readHolds获取当前线程读锁的次数并加一
head
write
read
。。。
AbstractQueuedSynchronizer#releaseShared
AbstractQueuedSynchronizer#signalNext
如果当前没有人获取到锁AbstractQueuedSynchronizer#tryAcquireShared
如果有共享锁或持有独占锁的线程不是当前线程,则尝试失败否则修改 state
readerShouldBlock判断是否需要阻塞
当前共享线程是否为 0
通过readHolds对每个线程自己的计数器进行--
为 0
LockSupport#park阻塞,等待 unpark
firstReader是否为当前线程
ReentrantReadWriteLock.Sync#tryReleaseShared
writerShouldBlock
失败
acquireShared
AbstractQueuedSynchronizer#acquire详情看 aqs
公平
否
可以防止这种
这种情况防不住
就是读锁计数减-
并通过 cas 尝试添加到同步队列队尾
公平锁判断阻塞队列是否有有效节点非公平锁直接返回 false
tryAcquire
获取共享锁成功
cas 尝试修改 state
ReentrantReadWriteLock.Sync#exclusiveCount如果有写锁并且不是当前线程则获取失败
是否为公平锁
是
ReentrantReadWriteLock.Sync#tryAcquireShared尝试获取共享锁
cas 修改 state获取共享锁
如果共享锁的数量等于 0
ReadLock.lock
不为 0
ReadLock.unlock
firstReaderHoldCount++;
继续进行 acquire 里面的死循环
acquire
firstReaderHoldCount--
创建一个 node node.waiter=当前线程
前置节点是否为头节点通过spins字段和Thread.onSpinWait();进行自旋
如果有中断则返回 true
AbstractQueuedSynchronizer#acquire获取共享锁
false
AbstractQueuedSynchronizer#apparentlyFirstQueuedIsExclusive简单来说就是如果头结点的下一个节点为共享节点就可以不阻塞可能会造成写锁饥饿
AbstractQueuedSynchronizer#hasQueuedPredecessors如果队列中有有效节点,则直接阻塞
修改下个节点的状态
是否有下一个节点,且status!=0
非公平
fullTryAcquireShared完整的获取读锁逻辑基本上与上面类似
state是否为 0
WriteLock.lock
设置firstReader为当前线程设置firstReaderHoldCount为 1
LockSupport.unpark唤醒线程
0 条评论
下一页