Java 利用 JUC CountDownLatch 线程池 Executors 实现多线程操作
作者:javaNice
- 2023-11-06 四川
本文字数:2311 字
阅读完需:约 8 分钟
Java 利用 JUC CountDownLatch 线程池 Executors 实现多线程操作
业务场景:某个业务操作非常耗时,但又必须等这个操作结束后才能进行后续操作
import org.springframework.util.CollectionUtils;
import java.util.List;import java.util.concurrent.CountDownLatch;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.TimeUnit;import java.util.function.Consumer;import java.util.stream.Collectors;import java.util.stream.Stream;
/** * 多线程任务处理工具类 * gzh-JavaNice */public class TaskDisposeUtils { //并行线程数 public static final int POOL_SIZE; static { //判断核心线程数 如果机器的核心线程数大于5则用机器核心线程数 POOL_SIZE = Integer.max(Runtime.getRuntime().availableProcessors(), 5); } /** * 并行处理,并等待结束 * * @param taskList 任务列表 * @param consumer 消费者 * @param <T> * @throws InterruptedException */ public static <T> void dispose(List<T> taskList, Consumer<T> consumer) throws InterruptedException { dispose(true, POOL_SIZE, taskList, consumer); } /** * 并行处理,并等待结束 * * @param moreThread 是否多线程执行 * @param poolSize 线程池大小 * @param taskList 任务列表 * @param consumer 消费者 * @param <T> * @throws InterruptedException */ public static <T> void dispose(boolean moreThread, int poolSize, List<T> taskList, Consumer<T> consumer) throws InterruptedException { if (CollectionUtils.isEmpty(taskList)) { return; } //如果是多线程且核心线程数大于一则进入方法 if (moreThread && poolSize > 1) { poolSize = Math.min(poolSize, taskList.size()); ExecutorService executorService = null; try { //新建一个固定大小的线程池 核心线程数为poolSize executorService = Executors.newFixedThreadPool(poolSize); //juc工具类 用于让必须所有任务都处理完后才进行下一步 CountDownLatch countDownLatch = new CountDownLatch(taskList.size()); for (T item : taskList) { executorService.execute(() -> { try { //消费任务 consumer.accept(item); } finally { //处理完后减一 countDownLatch.countDown(); } }); } //在此等待 当countDownLatch变成0后才继续进行下一步 countDownLatch.await(); } finally { if (executorService != null) { executorService.shutdown(); } } } else { for (T item : taskList) { consumer.accept(item); } } } public static void main(String[] args) throws InterruptedException { //生成1-10的10个数字,放在list中,相当于10个任务 List<Integer> list = Stream.iterate(1, a -> a + 1).limit(10).collect(Collectors.toList()); JSONObject object=new JSONObject(); 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 { 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(); } }); //上面所有任务处理完毕完毕之后,程序才能继续 System.out.println(list + "中的任务都处理完毕!"); }}
复制代码
执行结果
🖊️最后总结
🖲要熟练掌握技巧,一定多多坚持练习:骐骥一跃,不能十步;驽马十驾,功在不舍。
划线
评论
复制
发布于: 刚刚阅读数: 5
版权声明: 本文为 InfoQ 作者【javaNice】的原创文章。
原文链接:【http://xie.infoq.cn/article/85371a7236bd113140488333c】。文章转载请联系作者。
javaNice
关注
还未添加个人签名 2023-11-02 加入
还未添加个人简介










评论