千家信息网

什么是CountDownLatch

发表于:2025-02-01 作者:千家信息网编辑
千家信息网最后更新 2025年02月01日,今天就跟大家聊聊有关什么是CountDownLatch,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。countDownLatch也是基于AQS
千家信息网最后更新 2025年02月01日什么是CountDownLatch

今天就跟大家聊聊有关什么是CountDownLatch,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。

countDownLatch也是基于AQS,它是AQS共享功能的一个实现
1
countDownLatch构造
public CountDownLatch(int count) {
if (count < 0) throw new IllegalArgumentException("count < 0");
this.sync = new Sync(count);
}
count最终传递给state ,countDown也是对于state状态的改变

private static final class Sync extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = 4982264981922014374L;

Sync(int count) {
setState(count);
}

int getCount() {
return getState();
}

protected int tryAcquireShared(int acquires) {
return (getState() == 0) ? 1 : -1;
}
}

2 countDown实现

public void countDown() {
sync.releaseShared(1);
}

public final boolean releaseShared(int arg) {
if (tryReleaseShared(arg)) {
doReleaseShared();
return true;
}
return false;
}
protected boolean tryReleaseShared(int releases) {
// Decrement count; signal when transition to zero
for (;;) {
int c = getState();
if (c == 0)
return false;
int nextc = c-1;
if (compareAndSetState(c, nextc))
return nextc == 0;
}
}

private void unparkSuccessor(Node node) {
/*
* If status is negative (i.e., possibly needing signal) try
* to clear in anticipation of signalling. It is OK if this
* fails or if status is changed by waiting thread.
*/
int ws = node.waitStatus;
if (ws < 0)
compareAndSetWaitStatus(node, ws, 0);

/*
* Thread to unpark is held in successor, which is normally
* just the next node. But if cancelled or apparently null,
* traverse backwards from tail to find the actual
* non-cancelled successor.
*/
Node s = node.next;
if (s == null || s.waitStatus > 0) {
s = null;
for (Node t = tail; t != null && t != node; t = t.prev)
if (t.waitStatus <= 0)
s = t;
}
if (s != null)
LockSupport.unpark(s.thread);
}

3 await()实现 1、public void await() throws InterruptedException {sync.acquireSharedInterruptibly(1);}2、public final void acquireSharedInterruptibly(int arg)throws InterruptedException {if (Thread.interrupted())throw new InterruptedException();if (tryAcquireShared(arg) = 0) { // state的状态是0,说明,countDown的所有任务已经完成setHeadAndPropagate(node, r); //主线程所在的节点设置为头节点p.next = null; // help GCfailed = false;return; //主线程结束等待}}if (shouldParkAfterFailedAcquire(p, node) &&parkAndCheckInterrupt())throw new InterruptedException();}} finally {if (failed) //如果是非正常退出的话,取消cancelAcquire(node);}}private void setHeadAndPropagate(Node node, int propagate) {Node h = head; // Record old head for check belowsetHead(node);if (propagate > 0 || h == null || h.waitStatus 0) {do {node.prev = pred = pred.prev;} while (pred.waitStatus > 0);pred.next = node;} else {//讲等待状态设置为后继唤醒compareAndSetWaitStatus(pred, ws, Node.SIGNAL);}return false;}// 当前线程阻塞,判断线程是否中断private final boolean parkAndCheckInterrupt() {LockSupport.park(this);return Thread.interrupted();}//取消当前节点获取锁private void cancelAcquire(Node node) {// Ignore if node doesn't existif (node == null)return;node.thread = null;// Skip cancelled predecessorsNode pred = node.prev;while (pred.waitStatus > 0)node.prev = pred = pred.prev;Node predNext = pred.next; //如果节点都没有被取消的话,那么这个节点和node是同一个节点//node的后继节点取消node.waitStatus = Node.CANCELLED;// If we are the tail, remove ourselves.// CountDownLatch 逻辑就到这里if (node == tail && compareAndSetTail(node, pred)) {compareAndSetNext(pred, predNext, null);} else {int ws;if (pred != head &&((ws = pred.waitStatus) == Node.SIGNAL ||(ws <= 0 && compareAndSetWaitStatus(pred, ws, Node.SIGNAL))) &&pred.thread != null) {Node next = node.next;if (next != null && next.waitStatus <= 0)compareAndSetNext(pred, predNext, next);} else {unparkSuccessor(node);}node.next = node; // help GC}}countdownlatch通过检查state,是否为0 ,判断所有任务是否已经完成

看完上述内容,你们对什么是CountDownLatch有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注行业资讯频道,感谢大家的支持。

0