本文只是对多线程的一些简单实用(多核情况),比如数据库插入数据,计算数据(互不干扰,无需依赖上一个计算数据的)。
对数据进行一些处理,需要将大量的数据分成多个集合,这样才方便计算,比如将1000条数据,分成4分,这样一个线程只要处理250条数据(之前看过一篇文章,好像是线程不易过多,否则会影响速度)。这里附上大佬写的工具类连接:分割集合的工具类。这样就可以将数据分割。
public List<EmissionFillAccountingGHGDesc> queryMonthGHGData(Integer totalSize, List<List<EmissionFillFormTo>> list , String inventoryId, String emissionId) {
List<EmissionFillAccountingGHGDesc> resultList = new ArrayList<>();
//线程数量
int threadNum = list.size();
//线程处理数量(数据总量/线程量)
int threadSize = totalSize/threadNum;
//获取当前cpu的核心数
int i1 = Runtime.getRuntime().availableProcessors();
//线程池
ThreadPoolExecutor executor = new ThreadPoolExecutor(
4,//自定义线程数量
i1 * 2, //线程池最大线程数量(最大通常 i1/(1-(0.8~0.6))
60L, //线程存活时间
TimeUnit.SECONDS, //线程存活时间单位
new SynchronousQueue<Runnable>(),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.DiscardPolicy());
//其实就是计数器,同时只能有一个线程操作该计数器
CountDownLatch countDownLatch = new CountDownLatch(threadNum);
for (int i = 0; i < threadNum; i++){
//每个线程处理的数据
List<List<EmissionFillFormTo>> collect = list.stream().skip(i * threadSize).limit(threadSize).collect(Collectors.toList());
executor.execute(() ->{
//具体的业务
List<EmissionFillAccountingGHGDesc> emissionFillAccountingGHGDescs = this.queryData(collect, inventoryId, emissionId);
resultList.addAll(emissionFillAccountingGHGDescs);
countDownLatch.countDown();
});
}
try{
//等待时间
countDownLatch.await();
}catch (Throwable e){
}
//关闭线程池,如果此步没有执行,说明线程池有问题
executor.shutdown();
return resultList;
}
这样基本就实现了线程池的基本使用,当然是最基本的使用,可能会有一些问题,使用时也请注意。