线程池和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对获取图片的操作进行拆分,并行的获取图片,这样也就缩短了总的获取时间。

相关推荐
微小冷5 分钟前
Python图论库NetworkX初步
开发语言·python·图论·graph·networkx·digraph
宠友信息23 分钟前
内容社区源码开发实践解析,用Spring Boot打造1:1仿小红书源码平台
java·spring boot·redis·websocket·mysql·spring·uni-app
行百里er35 分钟前
加个依赖就生效?一行搞定 Spring Boot Starter 自动装配
java·后端·监控
月华路42 分钟前
G1 新生代对象晋升老年代:实现机制与 GC 日志
java·jvm·算法
万法若空1 小时前
排列组合恒等式
c++·算法
Data_Journal1 小时前
如何使用 Python 抓取 Google Flights:分步指南
大数据·开发语言·数据库·python·scrapy
AI人工智能+电脑小能手1 小时前
大白话说Java设计模式-34-命令模式(业务实战篇)
java·spring·设计模式·命令模式·异步任务·撤销重做·事务封装
Nil2081 小时前
leetcode 105从前序和中序遍历序列构造二叉树
算法·leetcode·职场和发展
净重21克1 小时前
万字长文!TLS协议升级避坑手册:JDK老项目适配TLS1.2/1.3全流程拆解
java·springboot·java安全
一直C1 小时前
【数据结构】哈希表+算法复杂度与经典排序查找(C语言)
java·linux·开发语言·数据结构·算法·ubuntu·散列表