项目场景:

简述项目相关背景:
例如:获取大量数据并处理,生成execl文件导出


问题描述:

5W条数据处理后生成execl文件需要6个小时,效率慢 APP 中接收数据代码:

@Overridepublic void run() {bytes = mmInStream.read(buffer);mHandler.obtainMessage(READ_DATA, bytes, -1, buffer).sendToTarget();}

原因分析:

数据量太多


解决方案:

使用多线程批量处理数据,下面是线程类,直接复制即可

package com.wwhl.cms.service.impl;import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;/*** @param <H> 为被处理的数据类型* @param <T>返回数据类型*/
public abstract class MultiThread<H,T>{private final ExecutorService exec; //线程池private final BlockingQueue<Future<T>> queue = new LinkedBlockingQueue<>();private final CountDownLatch startLock = new CountDownLatch(1); //启动门,当所有线程就绪时调用countDownprivate final CountDownLatch endLock; //结束门private final List<H> listData;//被处理的数据/*** @param list list.size()为多少个线程处理,list里面的H为被处理的数据*/public MultiThread(List<H> list){if(list!=null&&list.size()>0){this.listData = list;exec = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); //创建线程池,线程池共有nThread个线程endLock = new CountDownLatch(list.size());  //设置结束门计数器,当一个线程结束时调用countDown}else{listData = null;exec = null;endLock = null;}}/**** @return 获取每个线程处理结速的数组* @throws InterruptedException* @throws ExecutionException*/public List<T> getResult() throws InterruptedException, ExecutionException{List<T> resultList = new ArrayList<>();if(listData!=null&&listData.size()>0){int nThread = listData.size(); //线程数量,可根据系统性能自定义线程数for(int i = 0; i < nThread; i++){H data = listData.get(i);Future<T> future = exec.submit(new Task(i,data){@Overridepublic T execute(int currentThread,H data) {return outExecute(currentThread,data);}}); //将任务提交到线程池queue.add(future); //将Future实例添加至队列}startLock.countDown(); //所有任务添加完毕,启动门计数器减1,这时计数器为0,所有添加的任务开始执行endLock.await(); //主线程阻塞,直到所有线程执行完成for(Future<T> future : queue) {resultList.add(future.get());}exec.shutdown(); //关闭线程池}return resultList;}/*** 每一个线程执行的功能,需要调用者来实现* @param currentThread 线程号* @param data 每个线程被处理的数据* @return T返回对象*/public abstract T outExecute(int currentThread,H data);/*** 线程类*/private abstract class Task implements Callable<T>{private int currentThread;//当前线程号private H data;public Task(int currentThread,H data){this.currentThread=currentThread;this.data=data;}@Overridepublic T call() throws Exception {startLock.await(); //线程启动后调用await,当前线程阻塞,只有启动门计数器为0时当前线程才会往下执行T t =null;try{t = execute(currentThread,data);}finally{endLock.countDown(); //线程执行完毕,结束门计数器减1}return t;}/*** 每一个线程执行的功能* @param currentThread 线程号* @param data 每个线程被处理的数据* @return T返回对象*/public abstract T execute(int currentThread,H data);}
}

使用多线程批量处理数据使用场景:

 /*** 分割list集合** @param dataList* @return*/public List<Card> subList(List<Card> dataList) {List<Card> resultlist = new ArrayList<>();//存放批量数据处理的总结果集if (null != dataList && dataList.size() > 0) {int pointsDataLimit = 10;//限制条数 10条一批  Integer size = dataList.size();//判断是否有必要分批if (pointsDataLimit < size) {//大于10条int part = size / pointsDataLimit;//分批数for (int i = 0; i < part; i++) {List<Card> listPage = dataList.subList(0, pointsDataLimit);  //10条数据Integer start = cardlist.size();//10条数据在总结果集的开始下标cardlist = testTime(listPage, resultlist );//返回拼接后的总结果集Integer end = resultlist .size();//10条数据在总结果集的结束下标for (i = start; i < end; i++) {//对总数据集的10条数据进行业务处理}//剔除已经处理过的10条数据dataList.subList(0, pointsDataLimit).clear();}if (!dataList.isEmpty()) {//小于10条cardlist = testTime(dataList, cardlist);//处理最后的数据}} else {}}return resultlist ;}
 /*** 多线程处理批量数据** @param splitList 处理数据* @param cardlist  处理后总数据** @return*/public List<Card> testTime(List<Card> splitList, List<Card> cardlistr) {List<Card> list = null;try {MultiThread<Card, Card> multiThread = new MultiThread<Card, Card>(splitList) {              @Overridepublic Card outExecute(int currentThread, Card data) {//业务处理/* String iccid = data.getIccid();String allOrder = cardServerService.findAllOrder(iccid);String allFlow = cardServerService.allFlowByiccid(iccid);String allUseFlow = cardServerService.allUseFlowByiccid(iccid);Card card = cardMapper.findByIccid(iccid);String monthFlow = card.getMonthFlow();data.setMonthFlow(monthFlow);data.setAllOrder(allOrder);data.setAllFlow(allFlow);data.setAllUseFlow(allUseFlow);return data;*///业务处理end}};list = multiThread.getResult();//返回结果for (Card ccar : list) {cardlist.add(ccar);//批量数据遍历放入总结果}} catch (Exception e) {e.printStackTrace();}return cardlist;}

Card实体

/*** 卡实体类*/
public class Card {/*** 主键id*/private Long id;/*** 卡号*/private String cardNum;
}

多线程处理大量数据 java相关推荐

  1. 多进程多线程处理文本数据

    运行环境 python 3.6 numpy 1.18 threadpool 1.3 内置库:multiprocessing 代码简介 实现一个通用多进程+多线程支持方法.可以动态支持其他functio ...

  2. 大数据 java 代码示例_功能Java示例 第7部分–将失败也视为数据

    大数据 java 代码示例 这是称为" Functional Java by Example"的系列文章的第7部分. 我在本系列的每个部分中开发的示例是某种"提要处理程序 ...

  3. 大数据 java 代码示例_Java变量类型与示例

    大数据 java 代码示例 Java变量 (Java variables) Variables are the user-defined names of the memory blocks, and ...

  4. 大数据+java交流微信群

    一起进行大数据+Java的知识传递与分享,快来加入吧!! 本人程序员,发现身边很多朋友经常会问一些技术问题,特建立微信群供全国各地的朋友一起讨论学习,资源共享,本人也积累了很多专业性的资料,不定期分享 ...

  5. 一起重新开始学大数据-java篇-DAY01-第一个java代码helloworld

    一起重新开始学大数据-java篇 -DAY01-第一个java代码helloworld 计算机: 按照指定程序,自动高速处理海量数据 计算机组成 硬件和软件组成 硬件: cpu:计算 内存:提供计算资 ...

  6. JAVA-MySQL四{MySQL重点DQL查询数据}JAVA从基础开始 --7

    JAVA-MySQL四{MySQL重点DQL查询数据}JAVA从基础开始 --7 DQL查询语句 DQL - Data Query Language:数据查询语言 指定查询字段 1.全查 2.指定字段 ...

  7. 将一个整数转换为32位数据(java实现)

    将一个整数转换为32位数据(java实现) 将一个整数转换为二进制数据并且打印出来,都知道计算机底层使用32为数据来存储数据的.那么如何将一个整数通过代码的形式打印出来. 首先肯定需要用到位运算.通过 ...

  8. 【全集】大数据Java基础

    课程介绍 本课程是由猎豹移动大数据架构师,根据Java在公司大数据开发中的实际应用,精心设计和打磨的大数据必备Java课程.通过本课程的学习大数据新手能够少走弯路,以较短的时间系统掌握大数据开发必备语 ...

  9. 视频教程-大数据Java强化班(十)之大数据爬虫-Java

    大数据Java强化班(十)之大数据爬虫 10年一线开发及项目管理经验,6年以上大数据项目架构.实施.开发与运维经验,骨灰级大数据玩家,对Hadoop.Storm.Spark.Flink.Kylin.D ...

最新文章

  1. 关于使用Windows Live Writer
  2. matlba 正交基
  3. 20179214 2017-2018 2《网络攻防实践》第七周学习总结
  4. 认识 android-job
  5. 不同程序用不同网络_微信小程序直播登场,与平台直播有何不同?
  6. PHP - windows下编译PHP 7.2的memcache
  7. baseresponse响应类_Java response响应体和文件下载实现原理
  8. Linux 命令之 set -- 显示或设置 shell 特性及 shell 变量
  9. python while循环if_初入python 用户输入,if,(while 循环)
  10. [最小割] Luogu P4662 黑手党
  11. 读《向外行一样思考、像专家一样实践》之 简单、省略、抽象化、例子分析
  12. MySQL设置字符编码
  13. 国产Linux下的录屏软件
  14. Spring中@DependsOn注解的作用及实现原理解析
  15. 心形函数的正确打开方式(Unity3D Shader)
  16. 义乌集训Day 6 T2
  17. IBM Cloud 2015 - Invoice - 06 账期 Credit term, payment days, Net 30 days terms
  18. (一) Vue在创建的时候 入口文件 及相关的路由配置(及子路由配置)
  19. 研一Python基础课程第一周课后习题分享(含代码)
  20. 一卡通技术IC卡概述及分类

热门文章

  1. 注塑机计算机控制器,注塑机微机控制器,Microprocessor-based Controller for PIM,音标,读音,翻译,英文例句,英语词典...
  2. Android版本自带游戏,植物大战僵尸自带花园版
  3. Redis学习笔记(五)——持久化及redis.conf配置文件叙述
  4. Redis 配置文件解读
  5. 报错 | error ‘App‘ is not defined no-undef
  6. Unity 版本更新
  7. BeanUtils.populate(Object Bean,Map properties)
  8. 【生信分析】生物分子网络构建基础——酶动力学
  9. 数量X金额=总额 再例如X抽成0.08等出抽成金额180,大师们帮忙改一下下,万分感谢!
  10. SUG 180 Inversions(树状数组+离散化)