CountDownLatch
CountDownLatch是一个计数用的同步器类,先设定一个初始值,当计数降到0时,将会触发一些事件。
使用Demo
public static void main(String[] args) {
CountDownLatch countDownLatch = new CountDownLatch(5);
for (int i = 0; i < 5; i++) {
new Thread(() -> {
try {
Thread.sleep(3000);
System.out.println("线程" + Thread.currentThread().getName() + "执行结束");
countDownLatch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
System.out.println("等待线程执行结束");
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程执行结束");
}
存储结构与构造函数
private final Sync sync;
public CountDownLatch(int count) {
if (count < 0) throw new IllegalArgumentException("count < 0");
this.sync = new Sync(count);
}
- 内部类Sync实现了AQS接口:
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;
}
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;
}
}
}
由Sync实现的接口可知:
- 我们定义的计数初始值count,即为AQS中的状态state值;
- CountDownLatch实现的是 共享锁 ;
核心方法await
public void await() throws InterruptedException {
sync.acquireSharedInterruptibly(1);
}
其中acquireSharedInterruptibly方法是AQS中的实现:
public final void acquireSharedInterruptibly(int arg)
throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
if (tryAcquireShared(arg) < 0)
doAcquireSharedInterruptibly(arg);
}
- 我们只需要关注其实现的tryAcquireShared方法——tryAcquireShared(1)尝试获取共享锁:
protected int tryAcquireShared(int acquires) {
return (getState() == 0) ? 1 : -1;
}
- 返回1:表示获取共享锁成功(因为state=0表示无锁状态)
- 返回-1:表示获取共享锁失败
核心方法countDown
public void countDown() {
sync.releaseShared(1);
}
其中releaseShared方法是AQS中的实现:
public final boolean releaseShared(int arg) {
if (tryReleaseShared(arg)) {
doReleaseShared();
return true;
}
return false;
}
- 我们关注同步器实现的tryReleaseShared方法:
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;
}
}
- 如果当前state已经是0,表示锁没有被线程占有,返回false
- CAS将state-1,如果成功,返回当前state是否已经为0