什么是CountDownLatch?
CountDownLatch是 juc包下的一个同步辅助类。它允许一个或多个线程等待其他一组线程完成操作,再继续执行。
用法:
-
构造时 设定一个初始计数值(比如 N)。
-
等待线程 调用
await()方法,会被阻塞,直到计数器减到 0。 -
工作线程 在完成某项任务后,调用
countDown()方法,将计数器减 1。
CountDownLatch原理
构造器原理
public CountDownLatch(int count) {
if (count < 0) throw new IllegalArgumentException("count < 0");
this.sync = new Sync(count);
}
这个构造器本质是为Sync构造,赋值state
countDown原理
public void countDown() {
sync.releaseShared(1);
}
public final boolean releaseShared(int arg) {
if (tryReleaseShared(arg)) {
signalNext(head);
return true;
}
return false;
}
countDown的本质是释放一个资源。
protected boolean tryReleaseShared(int releases) {
// 自旋CAS,通过state==0来判断释放要唤醒线程
for (;;) {
int c = getState();
if (c == 0)
return false;
int nextc = c - 1;
if (compareAndSetState(c, nextc))
return nextc == 0;
}
}
非常普通的一个自旋CAS
await原理
public void await() throws InterruptedException {
sync.acquireSharedInterruptibly(1);
}
public final void acquireSharedInterruptibly(int arg)
throws InterruptedException {
if (Thread.interrupted() ||
(tryAcquireShared(arg) < 0 &&
acquire(null, arg, true, true, false, 0L) < 0))
throw new InterruptedException();
}
await的本质是获取共享锁
protected int tryAcquireShared(int acquires) {
return (getState() == 0) ? 1 : -1;
}
重写后的tryAcquireShared粗俗易懂,当state==0就可以获得锁,不等于零直接阻塞。