Java 利用JUC CountDownLatch 线程池Executors 实现多线程操作

简介: Java 利用JUC CountDownLatch 线程池Executors 实现多线程操作业务场景:某个业务操作非常耗时,但又必须等这个操作结束后才能进行后续操作

Java 利用JUC CountDownLatch 线程池Executors 实现多线程操作

业务场景:某个业务操作非常耗时,但又必须等这个操作结束后才能进行后续操作

importorg.springframework.util.CollectionUtils;

importjava.util.List;

importjava.util.concurrent.CountDownLatch;

importjava.util.concurrent.ExecutorService;

importjava.util.concurrent.Executors;

importjava.util.concurrent.TimeUnit;

importjava.util.function.Consumer;

importjava.util.stream.Collectors;

importjava.util.stream.Stream;

/**

* 多线程任务处理工具类

* gzh-JavaNice

*/

publicclassTaskDisposeUtils {

   //并行线程数

   publicstaticfinalintPOOL_SIZE;

   static {

       //判断核心线程数 如果机器的核心线程数大于5则用机器核心线程数

       POOL_SIZE=Integer.max(Runtime.getRuntime().availableProcessors(), 5);

   }

   /**

    * 并行处理,并等待结束

    *

    * @param taskList 任务列表

    * @param consumer 消费者

    * @param <T>

    * @throws InterruptedException

    */

   publicstatic<T>voiddispose(List<T>taskList, Consumer<T>consumer) throwsInterruptedException {

       dispose(true, POOL_SIZE, taskList, consumer);

   }

   /**

    * 并行处理,并等待结束

    *

    * @param moreThread 是否多线程执行

    * @param poolSize   线程池大小

    * @param taskList   任务列表

    * @param consumer   消费者

    * @param <T>

    * @throws InterruptedException

    */

   publicstatic<T>voiddispose(booleanmoreThread, intpoolSize, List<T>taskList, Consumer<T>consumer) throwsInterruptedException {

       if (CollectionUtils.isEmpty(taskList)) {

           return;

       }

       //如果是多线程且核心线程数大于一则进入方法

       if (moreThread&&poolSize>1) {

           poolSize=Math.min(poolSize, taskList.size());

           ExecutorServiceexecutorService=null;

           try {

               //新建一个固定大小的线程池 核心线程数为poolSize

               executorService=Executors.newFixedThreadPool(poolSize);

               //juc工具类 用于让必须所有任务都处理完后才进行下一步

               CountDownLatchcountDownLatch=newCountDownLatch(taskList.size());

               for (Titem : taskList) {

                   executorService.execute(() -> {

                       try {

                           //消费任务

                           consumer.accept(item);

                       } finally {

                           //处理完后减一

                           countDownLatch.countDown();

                       }

                   });

               }

               //在此等待 当countDownLatch变成0后才继续进行下一步

               countDownLatch.await();

           } finally {

               if (executorService!=null) {

                   executorService.shutdown();

               }

           }

       } else {

           for (Titem : taskList) {

               consumer.accept(item);

           }

       }

   }

  publicstaticvoidmain(String[] args) throwsInterruptedException {

       //生成1-10的10个数字,放在list中,相当于10个任务

       List<Integer>list=Stream.iterate(1, a->a+1).limit(10).collect(Collectors.toList());

       JSONObjectobject=newJSONObject();

       object.put("name","sss");

       //启动多线程处理list中的数据,每个任务休眠时间为list中的数值

//        Consumer<Integer> c= item -> {

//            try {

//                long startTime = System.currentTimeMillis();

//                object.put("s",item);

//                TimeUnit.SECONDS.sleep(item);

//                long endTime = System.currentTimeMillis();

//                System.out.println(object.toJSONString());

//                System.out.println(System.currentTimeMillis() + ",任务" + item + "执行完毕,耗时:" + (endTime - startTime));

//            } catch (InterruptedException e) {

//                e.printStackTrace();

//            }

//        };

       TaskDisposeUtils.dispose(list, item-> {

           try {

               longstartTime=System.currentTimeMillis();

               object.put("s",item);

               TimeUnit.SECONDS.sleep(item);

               longendTime=System.currentTimeMillis();

               System.out.println(object.toJSONString());

               System.out.println(System.currentTimeMillis() +",任务"+item+"执行完毕,耗时:"+ (endTime-startTime));

           } catch (InterruptedExceptione) {

               e.printStackTrace();

           }

       });

       //上面所有任务处理完毕完毕之后,程序才能继续

       System.out.println(list+"中的任务都处理完毕!");

   }

}

执行结果

🖊️最后总结

🖲要熟练掌握技巧,一定多多坚持练习:骐骥一跃,不能十步;驽马十驾,功在不舍


目录
相关文章
|
12月前
|
Java 开发者
Java并发编程:CountDownLatch实战解析
Java并发编程:CountDownLatch实战解析
670 100
|
安全 算法 Java
Java 多线程:线程安全与同步控制的深度解析
本文介绍了 Java 多线程开发的关键技术,涵盖线程的创建与启动、线程安全问题及其解决方案,包括 synchronized 关键字、原子类和线程间通信机制。通过示例代码讲解了多线程编程中的常见问题与优化方法,帮助开发者提升程序性能与稳定性。
536 0
|
机器学习/深度学习 消息中间件 存储
【高薪程序员必看】万字长文拆解Java并发编程!(9-2):并发工具-线程池
🌟 ​大家好,我是摘星!​ 🌟今天为大家带来的是并发编程中的强力并发工具-线程池,废话不多说让我们直接开始。
493 0
|
缓存 Java
线程池初始化严禁使用Executors
线程池初始化严禁使用Executors
|
11月前
|
设计模式 缓存 安全
【JUC】(6)带你了解共享模型之 享元和不可变 模型并初步带你了解并发工具 线程池Pool,文章内还有饥饿问题、设计模式之工作线程的解决于实现
JUC专栏第六篇,本文带你了解两个共享模型:享元和不可变 模型,并初步带你了解并发工具 线程池Pool,文章中还有解决饥饿问题、设计模式之工作线程的实现
699 2
|
存储 监控 Java
【Java并发】【线程池】带你从0-1入门线程池
欢迎来到我的技术博客!我是一名热爱编程的开发者,梦想是编写高端CRUD应用。2025年我正在沉淀中,博客更新速度加快,期待与你一起成长。 线程池是一种复用线程资源的机制,通过预先创建一定数量的线程并管理其生命周期,避免频繁创建/销毁线程带来的性能开销。它解决了线程创建成本高、资源耗尽风险、响应速度慢和任务执行缺乏管理等问题。
858 60
【Java并发】【线程池】带你从0-1入门线程池
|
Java 数据挖掘 调度
Java 多线程创建零基础入门新手指南:从零开始全面学习多线程创建方法
本文从零基础角度出发,深入浅出地讲解Java多线程的创建方式。内容涵盖继承`Thread`类、实现`Runnable`接口、使用`Callable`和`Future`接口以及线程池的创建与管理等核心知识点。通过代码示例与应用场景分析,帮助读者理解每种方式的特点及适用场景,理论结合实践,轻松掌握Java多线程编程 essentials。
901 5
|
数据采集 监控 调度
干货分享“用 多线程 爬取数据”:单线程 + 协程的效率反超 3 倍,这才是 Python 异步的正确打开方式
在 Python 爬虫中,多线程因 GIL 和切换开销效率低下,而协程通过用户态调度实现高并发,大幅提升爬取效率。本文详解协程原理、实战对比多线程性能,并提供最佳实践,助你掌握异步爬虫核心技术。
|
Java
线程池是什么?线程池在实际工作中的应用
总的来说,线程池是一种有效的多线程处理方式,它可以提高系统的性能和稳定性。在实际工作中,我们需要根据任务的特性和系统的硬件能力来合理设置线程池的大小,以达到最佳的效果。
403 18
|
Java 调度
【源码】【Java并发】【线程池】邀请您从0-1阅读ThreadPoolExecutor源码
当我们创建一个`ThreadPoolExecutor`的时候,你是否会好奇🤔,它到底发生了什么?比如:我传的拒绝策略、线程工厂是啥时候被使用的? 核心线程数是个啥?最大线程数和它又有什么关系?线程池,它是怎么调度,我们传入的线程?...不要着急,小手手点上关注、点赞、收藏。主播马上从源码的角度带你们探索神秘线程池的世界...
680 0
【源码】【Java并发】【线程池】邀请您从0-1阅读ThreadPoolExecutor源码