CountDownLatch 闭锁源码分析
2021-09-06 18:11:58 15 举报
CountDownLatch 闭锁源码分析
作者其他创作
大纲/内容
(getState() == 0) ? 1 : -1
否
prev
AQS Node 节点状态// 值为1,表示当前节点被取消;static final int CANCELLED = 1;// 值为-1,表示当前节点的的后继节点将要或者已经被阻塞,在当前节点释放的时候需要unpark后继节点;static final int SIGNAL = -1;// 值为-2,表示当前节点在等待condition,即在condition队列中;static final int CONDITION = -2;// 值为-3,表示releaseShared需要被传播给后续节点(仅在共享模式下使用);static final int PROPAGATE = -3;// 0:无状态,表示当前节点在队列中等待获取锁。
doAcquireSharedInterruptibly(int arg)
thread
return false;
nextWaiter
创建 SHARED 类型 Node
ws > 0
for
非空唤醒
只有 ws == SIGNAL 当前节点线程才能被 unpark
结束
LockSupport.unpark(s.thread);
next
continue;
初始化
CountDownLatch downLatch = new CountDownLatch(1);
Node h = head;
return Thread.interrupted();
创建节点(入队)
shouldParkAfterFailedAcquire 方法
false
unparkSuccessor(h);
激活节点 (出队)
修改为前驱节点为阻塞
是
是否是头节点
final Node node = addWaiter(Node.SHARED);
获取 AQS 头节点
h != null && h != tail
ws < 0
返回
r >= 0
ws == Node.SIGNAL
判断是否拿到锁
sync.releaseShared(1);
等待
new Sync(count);
tryAcquireShared(arg) < 0
注意这里是 await 不是 Object#wait
downLatch.await();
doAcquireSharedInterruptibly 方法
获取等待节点
return nextc == 0;
else
s != null
true
int ws = node.waitStatus;
查找有效的节点
开始
调用 CountDownLatch 中的的实现方法
tryAcquireShared(arg)
throw new InterruptedException();
LockSupport.park(this);
parkAndCheckInterrupt()
doReleaseShared 方法
int r = tryAcquireShared(arg);
唤醒节点
do { node.prev = pred = pred.prev; } while (pred.waitStatus > 0);pred.next = node;
break
当前线程进入阻塞
downLatch.countDown();
for (AbstractQueuedSynchronizer.Node t = tail; t != null && t != node; t = t.prev) if (t.waitStatus <= 0) s = t;
测试中断
h == head
p == head
唤醒线程
Thread.interrupted()
解锁
tryReleaseShared(arg)
doReleaseShared();
sync.acquireSharedInterruptibly(1);
int ws = h.waitStatus;
throw new InterruptedException();
unparkSuccessor(h); 方法
头节点是否为空
s == null || s.waitStatus > 0
final Node p = node.predecessor();
0 条评论
下一页