java使用CountDownLatch将一个任务拆解后合并处理

简介: java使用CountDownLatch将一个任务拆解后合并处理

一、事例代码

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
import java.util.logging.Logger;
 
public class CountDownLatchTest {
    //创建同步器
    private static CountDownLatch countDownLatch = new CountDownLatch(5);
 
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        //记录并打印开始时间
        long start = System.currentTimeMillis();
        System.out.println("startTima:"+start);
        //分拆任务后返回结果存放集合
        List<String> resList = new ArrayList<>();
        //创建固定大小线程池
        ExecutorService executorService = Executors.newFixedThreadPool(5);
        //创建多个Callable接口的实现
        CallAble can5 = new CallAble(4, countDownLatch, "我是线程5");
        CallAble can4 = new CallAble(4, countDownLatch, "我是线程4");
        CallAble can3 = new CallAble(3, countDownLatch, "我是线程3");
        CallAble can2 = new CallAble(2, countDownLatch, "我是线程2");
        CallAble can1 = new CallAble(1, countDownLatch, "我是线程1");
        //提交线程任务
        Future<List<String>> submit5 = executorService.submit(can5);
        Future<List<String>> submit4 = executorService.submit(can4);
        Future<List<String>> submit3 = executorService.submit(can3);
        Future<List<String>> submit2 = executorService.submit(can2);
        Future<List<String>> submit1 = executorService.submit(can1);  
        //等待所有线程返回结果
        countDownLatch.await();
        //将子线程结果添加到返回值集合
        resList.addAll(submit5.get());
        resList.addAll(submit4.get());
        resList.addAll(submit3.get());
        resList.addAll(submit2.get());
        resList.addAll(submit1.get());
        //销毁线程池
        executorService.shutdown();
        System.out.println("+++++++++++++++");
        //打印子线程结果
        resList.forEach(temm -> System.out.println(temm));
        //打印结果集大小
        System.out.println("temList.size:"+resList.size());
        //记录并打印结束时间
        long end = System.currentTimeMillis();
        System.out.println("endtime:"+end);
        System.out.println("总耗时:"+(end-start)/1000+"s");        
    }
}
//实现callable接口的实现类
class CallAble implements Callable<List<String>> {
    Logger log = Logger.getLogger("log");
    private int nun;
    //定义同步量
    private CountDownLatch cdl;
    //定义线程名称
    private String name;
    //构造方法
    public CallAble(int num, CountDownLatch countDownLatch, String name) {
        this.nun = num;
        this.cdl = countDownLatch;
        this.name = name;
    }
 
    @Override
    //实现callable接口call方法
    public List<String> call() throws Exception {
        //定义返回结果
        List<String> list = new ArrayList<>();
        System.out.println(Thread.currentThread().getName());
        try {
            //业务操作或者数据库的操作
            list.add(String.valueOf(this.nun));
            list.add(name);
            //程序休眠num秒
            Thread.sleep(this.nun*1000);
            System.out.println(name);
//            log.info(name);
        } finally {
            //计数器减一
            cdl.countDown();
        }
        return list;
    }
}

二、运行截图

相关文章
|
2月前
|
Java 开发者
Java并发编程:CountDownLatch实战解析
Java并发编程:CountDownLatch实战解析
402 100
|
4月前
|
人工智能 Java
Java多任务编排技术
JDK 5引入Future接口实现异步任务处理,但获取结果不够灵活。Java 8新增CompletableFuture,实现异步任务编排,支持流式处理、多任务组合及异常处理,提升执行效率与代码可读性,简化并发编程复杂度。
102 0
|
5月前
|
人工智能 Java Go
java判断ExecutorService是否有任务
在Java中,ExecutorService用于管理线程池。本文介绍如何判断ExecutorService是否有任务正在执行或等待执行。通过创建固定大小的线程池、提交任务,并使用`awaitTermination()`方法结合超时时间,可以有效检测任务状态。此方法简单实用,适用于多种场景。文末附有代码示例及详细解读。
101 1
|
6月前
|
Java 程序员 应用服务中间件
【高薪程序员必看】万字长文拆解Java并发编程!(2 2-2)
📌 核心痛点暴击:1️⃣ 面了8家都被问synchronized锁升级?一张图看懂偏向锁→重量级锁全过程!2️⃣ 线程池参数不会配?高并发场景下这些参数调优救了项目组命!3️⃣ volatile双重检测单例模式到底安不安全?99%人踩过的内存可见性大坑!💡 独家亮点抢先看:✅ 图解JVM内存模型(JMM)三大特性,看完再也不怕指令重排序✅ 手撕ReentrantLock源码,AQS队列同步器实现原理大揭秘✅ 全网最细线程状态转换图(附6种状态转换触发条件表)
110 0
|
6月前
|
存储 缓存 Java
【高薪程序员必看】万字长文拆解Java并发编程!(5):深入理解JMM:Java内存模型的三大特性与volatile底层原理
JMM,Java Memory Model,Java内存模型,定义了主内存,工作内存,确保Java在不同平台上的正确运行主内存Main Memory:所有线程共享的内存区域,所有的变量都存储在主存中工作内存Working Memory:每个线程拥有自己的工作内存,用于保存变量的副本.线程执行过程中先将主内存中的变量读到工作内存中,对变量进行操作之后再将变量写入主内存,jvm概念说明主内存所有线程共享的内存区域,存储原始变量(堆内存中的对象实例和静态变量)工作内存。
219 0
|
6月前
|
设计模式 缓存 安全
【高薪程序员必看】万字长文拆解Java并发编程!(8):设计模式-享元模式设计指南
🌟 ​大家好,我是摘星!​ 🌟今天为大家带来的是并发编程中的经典对象复用设计模式-享元模式,废话不多说让我们直接开始。
144 0
|
6月前
|
存储 安全 Java
【高薪程序员必看】万字长文拆解Java并发编程!(7):不可变类设计指南
🌟 ​大家好,我是摘星!​ 🌟今天为大家带来的是并发编程中Java不可变类设计指南,废话不多说让我们直接开始。
111 0
|
6月前
|
机器学习/深度学习 消息中间件 存储
【高薪程序员必看】万字长文拆解Java并发编程!(9-2):并发工具-线程池
🌟 ​大家好,我是摘星!​ 🌟今天为大家带来的是并发编程中的强力并发工具-线程池,废话不多说让我们直接开始。
227 0
|
6月前
|
网络协议 Java 大数据
【高薪程序员必看】万字长文拆解Java并发编程!(1)
📌 核心痛点暴击:1️⃣ 面了8家都被问synchronized锁升级?一张图看懂偏向锁→重量级锁全过程!2️⃣ 线程池参数不会配?高并发场景下这些参数调优救了项目组命!3️⃣ volatile双重检测单例模式到底安不安全?99%人踩过的内存可见性大坑!💡 独家亮点抢先看:✅ 图解JVM内存模型(JMM)三大特性,看完再也不怕指令重排序✅ 手撕ReentrantLock源码,AQS队列同步器实现原理大揭秘✅ 全网最细线程状态转换图(附6种状态转换触发条件表)
120 0