使用多线程批量处理数据

文章目录

  • 使用多线程批量处理数据

为什么要开启多线程处理?道理很简单,如果处理一千条数据需要10ms,那么串行处理1w条就要100ms,假如开启10个线程同时并发处理,只需要约10ms,速度提升将近十倍。当然实际上不会那么简单,需要综合考虑各种因素,但是毫无疑问使用多线程能够大大减少数据处理时长。

基本思路:

  1. 定义数据组大小,将数据分组。
  2. 定义任务。
  3. 确定线程池参数,新建线程池。
  4. 使用多线程执行任务。
  5. 合并处理结果。

下面简单来一个代码示例:

private void handleDataWithThreads() {// 创建模拟数据List<Person> data = createData(10100);// 1.数据分组List<List<Person>> lists = groupData(data, 1000);// 2.创建任务队列List<Callable<List<Person>>> taskList = new ArrayList<>();for (List<Person> list : lists) {Callable<List<Person>> task = new Callable<List<Person>>() {@Overridepublic List<Person> call() throws Exception {// 此处定义对数据的处理handleData(list);return list;}};taskList.add(task);}// 3.创建线程池// 参数:核心线程数;最大线程数;存活时间;存活时间单位;阻塞队列ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 10, 60,TimeUnit.SECONDS, new LinkedBlockingDeque<>());try {// 4.执行任务List<Future<List<Person>>> futures = executor.invokeAll(taskList);// 5.合并结果List<Person> resultList = new ArrayList<>();for (Future<List<Person>> future : futures) {resultList.addAll(future.get());}System.out.println(resultList);}catch (Exception e) {e.printStackTrace();}finally {executor.shutdown();}}/*** 数据处理* @param data*/private void handleData(List<Person> data) {log.info("当前线程:{},当前处理数据:{} - {}", Thread.currentThread(), data.get(0).getName(), data.get(data.size()-1).getName());for (Person person : data) {person.setName("new " + person.getName());person.setAge(person.getAge() + 10);}}/*** 生成模拟数据*/private List<Person> createData(int total) {List<Person> people = new ArrayList<>();for (int i = 0; i < total; i++) {Person person = new Person("person"+i, 18);people.add(person);}return people;}/*** 数据分组* @param sourceList* @param groupNum* @return*/private List<List<Person>> groupData(List<Person> sourceList, int groupNum) {List<List<Person>> targetList = new ArrayList<>();int size = sourceList.size();int remainder = size % groupNum;int sum = size / groupNum;for (int i = 0; i<sum; i++) {List<Person> subList;subList = sourceList.subList(i * groupNum, (i + 1) * groupNum);targetList.add(subList);}if (remainder > 0) {List<Person> subList;subList = sourceList.subList(size - remainder, size);targetList.add(subList);}return targetList;}

打印结果:

当前线程:Thread[pool-1-thread-10,5,main],当前处理数据:person9000 - person9999
当前线程:Thread[pool-1-thread-7,5,main],当前处理数据:person6000 - person6999
当前线程:Thread[pool-1-thread-1,5,main],当前处理数据:person0 - person999
当前线程:Thread[pool-1-thread-9,5,main],当前处理数据:person8000 - person8999
当前线程:Thread[pool-1-thread-6,5,main],当前处理数据:person5000 - person5999
当前线程:Thread[pool-1-thread-4,5,main],当前处理数据:person3000 - person3999
当前线程:Thread[pool-1-thread-3,5,main],当前处理数据:person2000 - person2999
当前线程:Thread[pool-1-thread-2,5,main],当前处理数据:person1000 - person1999
当前线程:Thread[pool-1-thread-8,5,main],当前处理数据:person7000 - person7999
当前线程:Thread[pool-1-thread-5,5,main],当前处理数据:person4000 - person4999
当前线程:Thread[pool-1-thread-4,5,main],当前处理数据:person10000 - person10099
………
  1. Java并发方面的知识就不在这里写了(其实我也不是很懂哈哈哈),关于线程池的定义、线程类型的选择等,根据自己的实际情况确定。
  2. 使用demo中的方式可以确保合并后数据的顺序和原来的一致。如果没有这种需要,可以遍历创建线程对象后直接执行并将结果添加到resultList,但是注意要resultList使用线程安全的类型。
  3. 影响执行速度的原因有很多,主要原因有数据组大小,线程数,分享本人使用中的一点小心得
  • 最好能够使每个线程的执行时间大致相同,避免出现某个线程执行时间过长导致总体时间加长。

  • 单个数据处理时间长,则将每组数据量缩减;反之则增加。

  • 线程数量其实没有一个统一的公式,总体原则是IO型线程数可以大点,CPU型线程数小点。具体情况还要自己多测试一番。

  • 需要好考虑并发的情况,每一次请求都创建一个线程池容易造成阻塞导致服务瘫痪,需要做限制或者创建一个全局线程池,这样即使多个请求进来也只是会影响到需要使用该线程池的方法。

使用多线程批量处理数据相关推荐

  1. 线程导入大数据入库_多线程批量插入数据小结

    在测试的过程中,无法避免的需要做一些性能压测,造数据的时长在此时就会备受关注.比如,造数据的时候用多线程还是多进程,用直接插入DB方式还是用先写文件后导入mysql的方式,写文件是写批量sql后面so ...

  2. HBase 高性能获取数据(多线程批量式解决办法) + MySQL和HBase性能测试比较

    转载于:http://www.cnblogs.com/wgp13x/p/4245182.html 摘要:   在前篇博客里已经讲述了通过一个自定义 HBase Filter来获取数据的办法,在末尾指出 ...

  3. java多线程批量读取文件(七)

    新公司入职一个多月了,至今没有事情可以做,十来个新同事都一样抓狂,所以大家都自己学习一些新东西,我最近在看zookeeper,感觉蛮不错的,和微服务的zuul以及eureka功能类似,只是代码复杂了一 ...

  4. python爆破端口_挑战全网多线程批量扫描爆破弱办事端口工具,Python制造专属!...

    挑战全网多线程批量扫描&爆破弱办事端口工具,Python制造专属!-1.jpg (29.47 KB, 下载次数: 0) 2018-8-16 17:05 上传 前言 你学习Python的目的是什 ...

  5. RedisCluster如何高效率地批量插入数据

    RedisCluster如何高效率地批量插入数据 Redis环境 入库方式 测试代码 redis工具类 测试接口 测试结果 Redis环境 RedisCluster: 三主三从,每个节点在单独的服务器 ...

  6. python利用多线程批量下载高清美女图片(350秒下载近3600张1.2个G的照片,地址可变)

    目录 第一章.前言 1.1.实现的效果: 1.2.需要用到的库: 第二章.代码分块讲解 2.1.对象的定义和初始化 2.2.方法1和2获取所有图集链接 2.2.1. 对应网站结构 2.2.2 .相应代 ...

  7. PHP多线程批量采集下载图片

    PHP多线程批量采集下载图片 博客分类: PHP 使用curl的多线程,另外curl可以设置请求时间,遇到很慢的url资源,可以果断的放弃,这样没有阻塞,另外有多线程请求,效率应该比较高,参考:< ...

  8. mysql批量设置自增_mysql自增id怎么批量插入数据

    使用mysql数据库--增 插入一条数据 首先,还是先解释一下如何使用数据库,按照上面的方法就可以连接数据库了.这里要解释两件事情. 1.执行sql语句返回的reCount是什么? 这个recount ...

  9. 【二十四】springboot使用EasyExcel和线程池实现多线程导入Excel数据

      springboot篇章整体栏目:  [一]springboot整合swagger(超详细 [二]springboot整合swagger(自定义)(超详细) [三]springboot整合toke ...

最新文章

  1. ATS 5.3.0中开启最高级别的缓存调试信息
  2. Linux下CMake简明教程(七)对库进行链接
  3. JavaScript获取当前日期时间
  4. VTK:PolyData之ShrinkPolyData
  5. 开放源代码_您对开放源代码感兴趣了多少年?
  6. 如果买一辆二手的劳斯莱斯在三线城市跑婚车,多久能回本?
  7. 从aspx后台页面向浏览器输出js文件
  8. 在vue中实现在线代码编辑器(lua) - ace/codemirror/monaco-editor
  9. NVIDIA CUDA各版本下载链接(包括最新11版本和以往10.2版本)
  10. dc持久内存与mysql_英特尔傲腾数据中心级持久内存的五大用例
  11. Ubuntu下的LibTorrent库编译
  12. 计算机保持在线的几种方法,获取网络电影实际地址的几种方法.doc
  13. Qt三种方式实现背景色和背景图(都可放缩,qss方式也可以)
  14. 关于SCI论文发表的五不准原则是
  15. NAT ALG DNS — DNS在外部,内网通过域名访问内部服务器
  16. amber中生成小分子模板
  17. 《初级会计电算化实用教程(金蝶KIS专业版)》一1.3 电算化会计信息系统
  18. git 快速清理本地分支_Git删除本地多个分支
  19. EXCEL中更改日期格式后,数据不刷新解决
  20. 托管C++中函数调用的双重转换(Double Thunking)

热门文章

  1. 碳酸锂、碳酸氢锂除钙镁离子交换柱
  2. Linux(Ubuntu)安装Django
  3. 控件注册失败原因汇集
  4. 牛顿在科学上的主要贡献在于构建起很多庞大的学科体系(从知识点向体系化发展):在物理学上,奠定了经典力学的基础;在数学上发现二项式定理,独立发明微积分。
  5. xp计算机管理下的服务显示不出来,在xp系统中,遇见电脑不显示摄像头图标怎么办?...
  6. 微信对话生成脚本,一键生成视频=脚本+教程
  7. CSS波形生成器-CSS Waves-Gradient Multiple Waves-Multiple Animated Waves
  8. 【无限互联】浅析开源框架SDWebImage
  9. 图书信息管理系统Java
  10. 爬取新浪社会新闻源代码