线程池和CountDownLatch搭配使用

一,CountDownLatch

CountDownLatch是Java并发编程中用于线程间协调的一个同步辅助类。它通过一个初始计数值来控制线程的等待,这个计数值在其他线程执行特定任务时递减。

  1. 初始化 :创建CountDownLatch实例时,你需要指定一个整数值,该值代表需要等待的事件或任务的数量。

  2. 递减计数countDown()方法用于减少CountDownLatch的当前计数值。每当一个关联的操作执行完毕,就调用此方法,从而向等待的线程发出信号。

  3. 等待完成await()方法用于阻塞当前线程,直到CountDownLatch的计数值达到0。这意味着主线程或其他等待的线程会在执行了await()调用的地方暂停,直到所有相关的countDown()操作完成。

  4. 灵活性countDown()可以被同一个线程多次调用,每次调用都会导致计数值减少。同时,如果有多个线程都在等待,它们会共享同一个CountDownLatch的计数值,当计数值减到0时,所有等待的线程都会被唤醒。

  5. 超时机制await()方法还可以接受一个超时时间参数,这样即使计数值没有在规定时间内减到0,等待的线程也会被唤醒,避免无限期等待。

  6. 结果汇总:在所有任务执行完毕后,主线程可以安全地继续执行,此时可以对子线程中的任务结果进行汇总或后续处理。

通过这种方式,CountDownLatch确保了在所有预定的任务或事件完成之前,主线程或其他线程不会过早地继续执行,从而实现了线程间的协调和同步。

二,示例

java 复制代码
public class 多线程结合countdownlatch {

    public static void main(String[] args) {
        //模拟任务
        List<String> records = new ArrayList<>();
        records.add("rc1");
        records.add("rc2");
        //线程池
        System.out.println("开始执行");
        ExecutorService service = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
        CountDownLatch latch = new CountDownLatch(records.size());
        records.forEach(record->{
            service.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        System.out.println(record);
                        Thread.sleep(2000);//执行业务逻辑
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }finally {
                        latch.countDown();
                    }
                }
            });
        });
        try {
            latch.await(30, TimeUnit.MINUTES);//设置超时时间 防止无限期等待
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("执行完成");
    }
}

三,使用场景

场景一:CountDownLatch 非常适合于对任务进行拆分,使其并行执行,比如某个任务执行2s,其对数据的请求可以分为五个部分,那么就可以将这个任务拆分为5个子任务,分别交由五个线程执行,执行完成之后再由主线程进行汇总,此时,总的执行时间将决定于执行最慢的任务,平均来看,还是大大减少了总的执行时间。

场景二:使用 CountDownLatch 的地方是使用某些外部链接请求数据的时候,比如图片。在本人所从事的项目中就有类似的情况,因为我们使用的图片服务只提供了获取单个图片的功能,而每次获取图片的时间不等,一般都需要1.5s~2s。当我们需要批量获取图片的时候,比如列表页需要展示一系列的图片,如果使用单个线程顺序获取,那么等待时间将会极长,此时我们就可以使用CountDownLatch对获取图片的操作进行拆分,并行的获取图片,这样也就缩短了总的获取时间。

相关推荐
Otaku love travel38 分钟前
老系统改造增加初始化,自动化数据源配置(tomcat+jsp+springmvc)
java·tomcat·初始化·动态数据源
DKPT1 小时前
Java设计模式之行为型模式(责任链模式)介绍与说明
java·笔记·学习·观察者模式·设计模式
L_autinue_Star1 小时前
手写vector容器:C++模板实战指南(从0到1掌握泛型编程)
java·c语言·开发语言·c++·学习·stl
我爱C编程1 小时前
基于Qlearning强化学习的1DoF机械臂运动控制系统matlab仿真
算法
晨岳1 小时前
CentOS 安装 JDK+ NGINX+ Tomcat + Redis + MySQL搭建项目环境
java·redis·mysql·nginx·centos·tomcat
chao_7891 小时前
CSS表达式——下篇【selenium】
css·python·selenium·算法
执笔诉情殇〆1 小时前
前后端分离(java) 和 Nginx在服务器上的完整部署方案(redis、minio)
java·服务器·redis·nginx·minio
元气小嘉1 小时前
前端技术小结
开发语言·前端·javascript·vue.js·人工智能
chao_7891 小时前
Selenium 自动化实战技巧【selenium】
自动化测试·selenium·算法·自动化
YuTaoShao2 小时前
【LeetCode 热题 100】24. 两两交换链表中的节点——(解法一)迭代+哨兵
java·算法·leetcode·链表