一、需求描述

利用线程池实现多线程分批执行任务。

例如:线程池容量为10,我有20个任务,第一次利用线程池中的10个线程异步执行完10个任务。10个任务完成后,不管任务成功或者失败,线程池回收10个线程继续完成剩下10个任务。

实际应用:当我们批量的需求比如启动1000个节点,启动一个节点的时间大概是3s,我们肯定不会去并行执行1000次启动,肯定是利用线程池的技术利用多线去异步启动1000个节点,但是我们又不可能给线程池1000个线程去准备,只能采用循环分批的思想去执行1000次启动。

二、代码示例

主函数:

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;import com.google.common.collect.Lists;public class BatchTest2 {public static void main(String[] args) throws InterruptedException {//线程池10个线程ExecutorService executorService = Executors.newFixedThreadPool(10);//第一批十个任务List<StartAgent> agentsStart = Lists.newArrayList(new StartAgent(),new StartAgent(),new StartAgent(),new StartAgent(),new StartAgent(),new StartAgent(),new StartAgent(),new StartAgent(),new StartAgent(),new StartAgent());//第二批十个任务List<StartAgent> agentsStart2 = Lists.newArrayList(new StartAgent(),new StartAgent(),new StartAgent(),new StartAgent(),new StartAgent(),new StartAgent(),new StartAgent(),new StartAgent(),new StartAgent(),new StartAgent());List<List<StartAgent>> task = new ArrayList<>();task.add(agentsStart);task.add(agentsStart2);//记录任务执行时间long t1 = System.currentTimeMillis();CountDownLatch c ;//循环任务组for(List<StartAgent> startList : task){//定义线程阻塞为10c = new CountDownLatch(10);for(StartAgent agent : startList){agent.setCountDownLatch(c);executorService.submit(agent);}//阻塞,等待十个任务都执行后,才继续下一批10任务c.await();}long t2 = System.currentTimeMillis();System.out.println("执行时间:"+  (t2 - t1)/1000);executorService.shutdown();}
}

StartAgent.java

import java.util.concurrent.CountDownLatch;public class StartAgent implements Runnable {private CountDownLatch countDownLatch;@Overridepublic void run() {try {System.out.println("开始启动节点:" + Thread.currentThread().getName());//模拟每个任务执行3秒钟Thread.sleep(3000);System.out.println(Thread.currentThread().getName() + "执行完毕");// 模拟执行任务异常// if(Thread.currentThread().getName().equals("pool-1-thread-4")){// System.out.println();// throw new InterruptedException("pool-1-thread-4启动失败");// }} catch (InterruptedException e) {e.printStackTrace();} finally {//注意一定要在finally调用countDown,否则产生异常导致没调用到countDown造成程序死锁countDownLatch.countDown();}}public void setCountDownLatch(CountDownLatch countDownLatch) {this.countDownLatch = countDownLatch;}}

三、调用结果

开始启动节点:pool-1-thread-1
开始启动节点:pool-1-thread-3
开始启动节点:pool-1-thread-5
开始启动节点:pool-1-thread-2
开始启动节点:pool-1-thread-6
开始启动节点:pool-1-thread-7
开始启动节点:pool-1-thread-4
开始启动节点:pool-1-thread-8
开始启动节点:pool-1-thread-9
开始启动节点:pool-1-thread-10
pool-1-thread-3执行完毕
pool-1-thread-1执行完毕
pool-1-thread-8执行完毕
pool-1-thread-9执行完毕
pool-1-thread-2执行完毕
pool-1-thread-5执行完毕
pool-1-thread-7执行完毕
pool-1-thread-4执行完毕
pool-1-thread-10执行完毕
pool-1-thread-6执行完毕
开始启动节点:pool-1-thread-3
开始启动节点:pool-1-thread-9
开始启动节点:pool-1-thread-2
开始启动节点:pool-1-thread-8
开始启动节点:pool-1-thread-1
开始启动节点:pool-1-thread-7
开始启动节点:pool-1-thread-10
开始启动节点:pool-1-thread-6
开始启动节点:pool-1-thread-5
开始启动节点:pool-1-thread-4
pool-1-thread-9执行完毕
pool-1-thread-2执行完毕
pool-1-thread-3执行完毕
pool-1-thread-8执行完毕
pool-1-thread-7执行完毕
pool-1-thread-1执行完毕
pool-1-thread-10执行完毕
pool-1-thread-5执行完毕
pool-1-thread-6执行完毕
pool-1-thread-4执行完毕
执行时间:6

可以看到,线程池先执行完第一批任务后,才执行第二批任务,而且每批任务都是异步执行,只用了3s,两批任务只用了6s。

以上只是一个简单的demo,提供一个思路,主要用到的知识点是CountDownLatch,网上对这个知识点介绍比较多了,我就不啰嗦了。

java多线程分批执行任务demo相关推荐

  1. java 多线程顺序执行

    这道阿里巴巴多线程面试题,你学会了没有? 置顶 2019年06月14日 15:43:55 XingXing_Java 阅读数 447 点关注,不迷路:持续更新Java相关技术及资讯!!! 前言 有个朋 ...

  2. Java 多线程同时执行

    我们创建三个任务与三个线程,让三个线程启动,同时执行三个任务. 任务类必须实现 Runable 接口,而 Runable 接口只包含一个 run 方法.需要实现 这个方法来告诉系统线程将如何运行. 创 ...

  3. 【无标题】java多线程分批同步数据设计与实现(转载)

      已识乾坤大,犹怜草木青.          --旷怡亭口占 文章目录 前言 设计思路 代码实践 前言 最近接到一个任务,将mysql中的数据同步到elasticsearch中,要求异步执行,接口不 ...

  4. Java 多线程分批同步数据

      已识乾坤大,犹怜草木青.          --旷怡亭口占 文章目录 前言 设计思路 代码实践 前言 最近接到一个任务,将mysql中的数据同步到elasticsearch中,要求异步执行,接口不 ...

  5. java多线程分批调用接口

    线程池工具类 public class ThreadPoolUtil {public static final long DEFAULT_WAIT_SECONDS = 5000;private sta ...

  6. java中thread实例_Java多线程并发执行demo代码实例

    主类:MultiThread,执行并发类 package java8test; import java.util.ArrayList; import java.util.List; import ja ...

  7. java商城项目中多线程执行_java多线程中执行多个程序的实例分析

    我们知道多线程因为同时处理子线程的能力,对于程序运行来说,能够达到很高的效率.不过很多人对于多线程的执行方法还没有尝试过,本篇我们将为大家介绍创建线程的方法,在这个基础上,对程序执行多条命令的方法进行 ...

  8. 使用java多线程分批处理数据工具类

    最近由于业务需要,数据量比较大,需要使用多线程来分批处理,提高处理效率和能力,于是就写了一个通用的多线程处理工具,只需要实现自己的业务逻辑就可以正常使用,现在记录一下 主要是针对大数据量list,将l ...

  9. JavaSE基础二十:Java 多线程(线程基础知识、Java 多线程、Java 实现多线程(继承 Thread 类、实现 Runnable 接口、实现 Callable 接口))

    本章目录 1.基础知识准备 2.Java 多线程概述 3.Java 实现多线程 3.1.继承 Thread 类 如何开启新线程 Thread 类常用方法 多线程中的同步 Thread 类同步方法 多线 ...

最新文章

  1. Linux下二进制文件安装MySQL
  2. kafka 发布订阅_在Kafka中发布订阅模型
  3. 我的iOS学习历程 - OC第九天
  4. .net core精彩实例分享 -- 应用配置和数据库访问
  5. “我的开源项目被大厂‘盗用’了!”
  6. .bat以管理员身份运行
  7. 总结全网最全的数据学习平台
  8. php发卡v6_GitHub - Cghang/vfkphp: V发卡 完全开源免费的个人自动发卡解决方案
  9. Rhino6.5软件安装教程|兼容WIN10
  10. MacOS破解WiFi(WPA、WPA2)
  11. java ldc指令_6.Java JVM_4.JVM字节码之整型入栈指令(iconst、bipush、sipush、ldc)
  12. 计算机专业硕士论文评语,硕士论文评审意见范文
  13. Ubuntu 22.04 ‘Jammy Jellyfish‘ 的新功能
  14. 欢乐的票圈重构——九宫格控件(上)
  15. 计算机专业毕业设计答辩稿
  16. Tableau性能提升
  17. session基本知识
  18. 客制化 GH60 XD60 像 Poker 一样的 60% 机械键盘 (2) 采购以及组装
  19. 小微企业信用评级方法
  20. html中bak是什么文件怎么打开,bak文件怎么打开

热门文章

  1. Java异步执行方法
  2. 英文e-mail的開頭稱呼
  3. 用CSS3实现的addidas阿迪达斯标志LOGO
  4. 复古油漆泼墨飞溅绘画效果ps动作
  5. wordcount.java_WordCount(java)
  6. 【C++】FindWindow
  7. 干海参的价格是多少谁有海参价格表啊
  8. React Fiber架构原理
  9. Android6.0 移除电池设置
  10. R/BioC序列处理之五:Rle和Ranges