CountDownLatch 原理
CountDownLatch(倒计时门闩)是Java中的一个同步工具类,用于在一个或多个线程等待其他线程执行完毕后再继续执行。其原理主要基于一个计数器,该计数器在初始化时设定一个值,每当一个线程完成了自己的任务后,计数器的值就会减一,当计数器的值变为零时,所有等待的线程都会被唤醒。
具体来说,CountDownLatch 原理如下:
- 初始化时设定一个计数器,表示需要等待的线程数量。
- 每个等待的线程在开始执行前,都会调用 CountDownLatch 的 await() 方法,使其进入等待状态。
- 每个执行完毕的线程都会调用 CountDownLatch 的 countDown() 方法,使计数器减一。
- 当计数器的值变为零时,所有等待的线程都会被唤醒,可以继续执行后续操作。
CountDownLatch 主要用于解决一个或多个线程需要等待其他线程完成某些操作后才能执行的场景,例如多个线程同时进行数据加载,但需要等待所有数据加载完毕后再进行后续处理,这时就可以使用 CountDownLatch 来实现线程间的协调与同步。
CountDownLatch 使用场景
CountDownLatch 主要用于以下场景:
- 并发控制: 当需要控制并发执行的线程数量时,可以使用 CountDownLatch。通过设置 CountDownLatch 的计数值,限制同时执行的线程数量。
- 服务启动控制:在分布式系统中,可能需要确保所有节点都启动完成后才对外提供服务。CountDownLatch 可以用来等待所有节点启动完成后再进行服务注册。
- 系统初始化:当一个系统启动时,可能需要执行多个初始化任务,如数据库连接、加载配置等。主线程可以使用 CountDownLatch 等待所有初始化任务完成后再继续执行。
- 测试用例:在多线程测试中,可能需要确保所有线程都执行完毕后才进行结果验证。CountDownLatch 可以用来等待所有测试线程执行完毕后再进行结果分析。
CountDownLatch 适用于需要等待其他线程完成某些操作后才能继续执行的场景,可以实现线程之间的协调与同步。
CountDownLatch 使用场景举例
CountDownLatch
的作用允许 count 个线程阻塞在一个地方,直至所有线程的任务都执行完毕。有一个使用多线程读取多个文件处理的场景,用到了 CountDownLatch
。具体场景是下面这样的:
要读取处理 8个文件,这8个任务都是没有执行顺序依赖的任务,但需要返回给用户的时候将这几个文件的处理的结果进行统计整理。
为此定义了一个线程池和 count 为8的CountDownLatch
对象 。使用线程池处理读取任务,每一个线程处理完之后就将 count-1,调用CountDownLatch
对象的 await()
方法,直到所有文件读取完之后,才会接着执行后面的逻辑。
代码举例:
public class CountDownLatchExample1 {
// 处理文件的数量
private static final int threadCount = 8;
public static void main(String[] args) throws InterruptedException {
// 创建一个具有固定线程数量的线程池对象(推荐使用构造方法创建)
ExecutorService threadPool = Executors.newFixedThreadPool(10);
final CountDownLatch countDownLatch = new CountDownLatch(threadCount);
for (int i = 0; i < threadCount; i++) {
final int threadnum = i;
threadPool.execute(() -> {
try {
//处理文件的业务操作
//......
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//表示一个文件已经被完成
countDownLatch.countDown();
}
});
}
countDownLatch.await();
threadPool.shutdown();
System.out.println("finish");
}
}
当然上述场景可以使用CompletableFuture来实现。
更多消息资讯,请访问昂焱数据。