CountDownLatch是Java并发包java.util.concurrent中的一个同步辅助类,它允许一个或多个线程等待直到在其他线程中执行的一组操作完成。CountDownLatch的工作原理是基于一个计数器,我们在创建CountDownLatch实例时指定计数器的初始值。每当一个指定的操作执行完成时,计数器的值就减一。当计数器的值达到零时,等待在CountDownLatch上的线程就会被唤醒,继续执行。
CountDownLatch的用法
CountDownLatch主要用于两种场景:
-
确保某个处理在其他线程运行完毕后再执行:可以在准备执行的线程中调用
CountDownLatch.await()方法等待其他线程完成各自的任务。其他线程在完成各自的任务后调用CountDownLatch.countDown()方法。这样,可以保证await()方法阻塞的线程会在其他线程的任务全部完成后继续执行。 -
同时开始执行一组操作:所有执行线程都调用
await()方法在CountDownLatch上等待,主线程完成一些前置设置后调用countDown()方法,这时所有等待的线程同时开始执行。
CountDownLatch的关键方法
-
CountDownLatch(int count):构造方法,
count指定了计数器的初始值。 -
void await() throws InterruptedException:使当前线程等待直到锁存器计数到达零,除非线程被中断。
-
boolean await(long timeout, TimeUnit unit) throws InterruptedException:让当前线程等待直到锁存器计数到达零,除非线程被中断,或者指定的等待时间过去。
-
void countDown():递减锁存器的计数,如果计数到达零,则释放所有等待的线程。
CountDownLatch的示例
考虑一个场景,我们需要加载一些配置数据,启动一些服务等初始化操作完成后,应用才能对外提供服务。我们可以使用CountDownLatch来达成这个需求:
import java.util.concurrent.CountDownLatch;
public class MainApplication {
public static void main(String[] args) throws InterruptedException {
// 初始化计数器为3
CountDownLatch latch = new CountDownLatch(3);
// 创建并启动3个线程
new Thread(new Service("Service-1", 1000, latch)).start();
new Thread(new Service("Service-2", 1000, latch)).start();
new Thread(new Service("Service-3", 1000, latch)).start();
// 主线程等待其他线程完成
latch.await();
System.out.println("All services are up, Application is starting now");
}
}
class Service implements Runnable {
private final String name;
private final int timeToStart;
private final CountDownLatch latch;
public Service(String name, int timeToStart, CountDownLatch latch) {
this.name = name;
this.timeToStart = timeToStart;
this.latch = latch;
}
@Override
public void run() {
try {
Thread.sleep(timeToStart);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println(name + " is Up");
latch.countDown(); // 减少锁存器的计数
}
}
在这个例子中,我们创建了一个CountDownLatch,其计数器的初始值为3,表示需要等待3个服务全部启动。每个Service线程模拟服务启动过程,并在启动后调用countDown()方法。主线程通过调用await()方法等待所有服务的启动。当所有服务线程调用countDown()方法使计数器减至0时,主线程被唤醒,继续执行。
小结
CountDownLatch是一个非常实用的并发工具类,它通过一个计数器提供了一种简单的线程同步机制。这使得它在如启动应用程序、等待服务初始化、完成一组并发任务等场景下非常有用。