CountDownLatch
也是同步的辅助工具,它允许一个或多个线程等待直到在其他线程中完成一组操作。CountDownLatch
由一个给定的count值初始化,其await()
操作会一直等待
直到countDown()
操作将count值递减为0为止,然后会释放所有阻塞的线程(即await后的所有操作都会立即返回)。但相比CyclicBarrier
这个操作只能执行一次,count不会被重置。
主要属性
1 | public class CountDownLatch { |
可以看出CountDownLatch
内部依赖Sync实现,而Sync继承了AQS。tryAcquireShared
和tryReleaseShared
两个方法的重写,可得出其是利用共享锁来实现的。
等待await()
1 | public void await() throws InterruptedException { |
没啥好说的利用同步锁的机制实现
countDown()
1 | public void countDown() { |
通过递减count值 将其递减为0,使得tryAcquireShared
中(getState() == 0) ? 1 : -1
返回为1 从而从阻塞中退出1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25private void doAcquireSharedInterruptibly(int arg)
throws InterruptedException {
final Node node = addWaiter(Node.SHARED);
boolean failed = true;
try {
for (;;) {
final Node p = node.predecessor();
if (p == head) {
int r = tryAcquireShared(arg);
if (r >= 0) {//退出自旋
setHeadAndPropagate(node, r);
p.next = null; // help GC
failed = false;
return;
}
}
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
throw new InterruptedException();
}
} finally {
if (failed)
cancelAcquire(node);
}
}