并发源码_CyclicBarrier源码分析
2023-03-29 16:03:27 0 举报
并发源码_CyclicBarrier源码分析
作者其他创作
大纲/内容
通知所有节点移动到同步队列当中,并将节点从条件队列删除
快速判断1:节点状态或者节点没有前置节点同步队列是有头节点的,而条件队列没有快速判断2:next字段只有同步队列才会使用,条件队列中使用的是nextWaiter字段
prev
修改节点信号量状态为0,失败直接返回false
transferForSignal(first)
判断是否为0index == 0
加锁
单链表出队操作(精髓do while) do { Node next = first.nextWaiter; first.nextWaiter = null; transferForSignal(first); first = next; } while (first != null)
加入同步队列尾部当中,返回前驱节点
next
ReetrantLock lock lockl.lock();
waitSatuts = 0thread --null
fist
将头结点的状态置为-1标识后面的节点需要唤醒
waitSatuts = -1thread --null
不为空
进入条件队列 trip.await()
waitSatuts = -1thread1
将节点从条件队列当中移动到同步队列当中,等待获取锁
first
await()dowait()
nextWaiter等待队列中的后继节点
判断是否有barrierCommand
lock.lock();try{ await(); 前半段,释放锁进入条件队列,然后阻塞线程 过渡阶段,被最终达到栅栏的线程singalAll唤醒线程(条件队列转到同步队列里) 可以在释放锁的时候唤醒head的后续的线程 后半段,获取锁(如果有竞争力,cas获取锁失败,还会阻塞) 释放锁(唤醒同步队列中的head的后续节点所在的线程) 后段班的逻辑就是独占锁的逻辑}finally{ lock.unlock();}
不是第一个进来的节点(入队操作) firstWaiter = nodet.nextWaiter = node lastWaiter = node
nextWaiter
不为0,入队阻塞
释放掉已经获取的独占锁资源 int savedState = fullyRelease(node)
把当前节点加入条件队列
为空
有限优先执行barrierCommand
判断尾节点是否为空
head tail
waitSatuts = 0thread1
阻塞当前线程LockSupport.park(this)
Node node = addConditionWaiter()
doSignalAll
waitSatuts = -2thread1
int index = --count
waitSatuts = -2thread2
Node p = enq(node)
如果不在同步队列中则不断挂起isOnSyncQueue
添加到条件队列中去(单向链表)1.与同步队列不同,条件队列头尾指针是firstWaiter跟lastWaiter2.条件队列是在获取锁之后,也就是临界区进行操作,因此很多地方不用考虑并发
有
nextGeneration
lock.unlock()
waitSatuts = 0thread2
第一个进来的节点 firstWaiter = node lastWaiter = node
0 条评论
回复 删除
下一页