多线程拆分list,合并list
标签:executor orm 存储 service 处理 utils interrupt Fix import
今天有一个接口20s 才能展示出来数据,这怎么可以领导直接让我去处理这个接口,处理不出来就不要下班了
我心中一紧 赶紧去看这是哪个垃圾写出来的代码
浏览了一下代码发现 需求是这样子的 后台请求一个地址 返回了一个list集合,我拿着这个list 集合对象的主键,再去调用查看详情接口,拼接到原来的对象上。最后在合并拼接上参数的对象集合。
以前的兄弟直接for循环调用,数据量不大 130多条数据 但是也需要20秒(1个接口调用150毫秒,帮大家算出来了)。
这怎么行,祭出大杀器,多线程。
我们需要用callable 的线程方法 因为我们还需要将返回值 给他拼回去 代码如下
package com.zhgw.dev.pioc.utils;
import com.alibaba.fastjson.JSONObject;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
public class PersionThread implements Callable {
/** 数据集合 */
private List list;
/** 权限 */
private String token;
/** 每个线程处理的起始数据 */
private CountDownLatch begin;
/** 每个线程处理的结束数据 */
private CountDownLatch end;
public PersionThread() {
}
public PersionThread(List list, CountDownLatch begin, CountDownLatch end,String token) {
this.list = list;
this.begin = begin;
this.end = end;
this.token = token;
}
@Override
public List call() throws Exception {
try {
if (list != null && !list.isEmpty()) {
// testBatchInsertMapper.batchInsert(list);
List PersionDTOArrayList = new ArrayList();
int size = list.size();
for (PersionDTO PersionDTO :list) {
String personString = HttpUtils.httpPostForm("http://www.baidu.com" + "?token=" + token + "&oid=" + PersionDTO.getInspectoroid(), null, false, "160");
}
//System.out.println("线程"+JSONObject.toJSONString(PersionDTOArrayList));
return PersionDTOArrayList;
}
// 执行完让线程直接进入等待
begin.await();
} catch (Exception e) {
e.printStackTrace();
} finally {
// 当一个线程执行完 了计数要减一不然这个线程会被一直挂起
end.countDown();
}
return null;
}
}
执行多线程的方法
public List batchInsertByThread(List list, String token){
if (list == null || list.isEmpty()) {
return null;
}
// 一个线程处理6条数据
int count = 7;
// 数据集合大小
int listSize = list.size();
// 开启的线程数
int runSize = (listSize / count) + 1;
// 存放每个线程的执行数据
List newList = null;
// 创建一个线程池,数量和开启线程的数量一样
ExecutorService executor = Executors.newFixedThreadPool(runSize);
// 创建两个个计数器
CountDownLatch begin = new CountDownLatch(1);
CountDownLatch end = new CountDownLatch(runSize);
List>> futures = new ArrayList>>();
// 创建一个存储所有返回值的list
List listAll = Collections.synchronizedList(new ArrayList());
for (int i = 0; i ) {
/* 计算每个线程执行的数据 */
if ((i + 1) == runSize) {
int startIdx = (i * count);
int endIdx = list.size();
newList = list.subList(startIdx, endIdx);
} else {
int startIdx = (i * count);
int endIdx = (i + 1) * count;
newList = list.subList(startIdx, endIdx);
}
PersionThread PersionThread = new PersionThread(newList, begin, end, token);
futures.add(executor.submit(PersionThread));
}
begin.countDown();
//System.out.println("submit"+ JSONObject.toJSONString(submit));
try {
for(Future> future : futures){
//合并操作
List PersionDTOS = null;
try {
PersionDTOS = future.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
listAll.addAll(PersionDTOS);
}
//System.out.println(JSONObject.toJSONString(listAll));
end.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
executor.shutdown();
return listAll;
}
调用线程的方法
public static void main(String[] args) {
R> listR = personnelGPS();
System.out.println(listR);
多线程拆分list,合并list
标签:executor orm 存储 service 处理 utils interrupt Fix import
原文地址:https://www.cnblogs.com/dupeilin/p/14247553.html
评论