CountDownLatch
CountDownLatch是一个同步器, 允许一个或多个线程执行完毕,再继续执行, 可以用来协调多个线程的同步。
CountDownLatch通过计数器实现, 计数器的初始值是线程的数量, 每当一个线程执行完毕, 计数器减1, 当计数器减为0或达到超时时间时, 等待的线程开始恢复执行。
应用场景
-
某一个线程等待n个线程执行完毕, CountDownLatch初始化为CountDownLatch(n), 当某个任务线程执行执行结束时,调用countDown方法,计数器减1, 当计数器减为0时, 表示n个任务线程全部执行完毕,await的线程被唤醒, 开始执行。典型场景为,主线程等待所有子任务结束,继续下一步。 比如服务启动时等待多个组件加载完毕,启动服务。
-
多个线程等待某个线程执行结束, 开始并发执行, CountDownLatch初始化为CountDownLatch(1), 每个等待线程启动时调用该CountDownLatch await方法被阻塞, 当主线程执行完成, 计数器减1, 同时唤醒多个等待线程开始执行。
重要方法
// 构造器
public CountDownLatch(int count) {}
//
public void await() throws InterruptedException {}
//
public boolean await(long timeout, TimeUnit unit) throws InterruptedException{}
//
public void countDown() {}
- 构造器
CountDownLatch的构造器仅有一个int参数, 代表阻塞的线程数量。 - await
调用此方法的线程会被挂起, 直到count值降为0才会被唤醒。 - await(long timeout, TimeUnit unit)
调用此方法的线程会被挂起, 直到count值降为0或超时才会被唤醒。 - countDown
调用此方法, count值减1
示例
- 主线程等待n个线程执行结束
final CountDownLatch countDownLatch = new CountDownLatch(10);
for(int i=0; i<10; i++){
final int finalI = i;
Runnable thread = new Runnable() {
@Override
public void run() {
System.out.println(finalI);
countDownLatch.countDown();
}
};
thread.run();
}
countDownLatch.await();
- 并发执行
ExecutorService service = Executors.newCachedThreadPool();
final CountDownLatch countDownLatch = new CountDownLatch(1);
final CountDownLatch countDownLatch1 = new CountDownLatch(10);
final int[] a = {0};
for(int i=0; i<10; i++){
Runnable thread = new Runnable() {
@Override
public void run() {
try {
System.out.println(a[0]);
countDownLatch.await();
a[0] += 1;
countDownLatch1.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
service.execute(thread);
}
countDownLatch.countDown();
countDownLatch1.await();
System.out.println(a[0]);
原理解析
TODO AQS
网友评论