项目中多线程的应用
项目中有个功能,需要查询多条指标数据,而指标数据需要多表联查处理,查询比较慢,因此用线程池实现:
代码中涉及了FutureTask的用法,这是有返回值的处理实现,先将要处理的数据执行逻辑放入FutureTask中,再有线程池调起执行,并且返回FutureTask,最后遍历FutureTask获取执行结果并返回。
延展—FutureTask使用
可以把FutureTask交给Executor执行;也可以通ExecutorService.submit(…)方法返回一个FutureTask,然后执行FutureTask.get()方法或FutureTask.cancel(…)方法。除此以外,还可以单独使用FutureTask。
具体可以参看FutureTask使用,链接:https://blog.csdn.net/qq_39654841/article/details/90631795
/**
* 查询数据分页每行展示4个 故 每个线程执行 4个
* @param paramList
* @return
* @throws InterruptedException
*/
@Override
public List<Map<String, Object>> queryMapIndData(List<Map<String, Object>> paramList, String orgCode) throws InterruptedException {
List<Map<String, Object>> reLists = Lists.newArrayList();
//默认卡片
String compType = ConstantsUtil.CD_CARD;
//默认T-1
String date = dateUtil.getYesterDay(new Date());
//每个线程4个
int execNum = 4;
//每个线程处理个数
int pageNo = paramList.size() % execNum == 0 ? paramList.size() / execNum : (paramList.size() / execNum) + 1 ;
List<FutureTask<List<Map<String, Object>>>> tasks = Lists.newArrayList();
//创建线程
for(int i = 0; i < pageNo; i++) {
List<Map<String, Object>> subList = null;
//小于4条
if(i == pageNo -1 ) {
subList = paramList.subList(i * 4, paramList.size());
} else {//大于等于4条
subList = paramList.subList(i * 4, (i + 1) * 4);
}
FutureTask<List<Map<String, Object>>> task = new FutureTask(new IndDataThread(subList, compType, date, orgCode));
threadPoolTaskExecutor.submit(task);
tasks.add(task);
}
//获取结果
for(FutureTask<List<Map<String, Object>>> task : tasks) {
try {
List<Map<String, Object>> list = task.get();
reLists.addAll(list);
} catch (ExecutionException e) {
logger.error("queryMapIndData 当前异常处理异常", e);
}
}
System.err.println("queryMapIndData -- reListCount = " + reLists.size());
return reLists;
}
正常情况用runable就可以,但是有返回值需要重写call()方法,代码如下
public IndDataThread(List<Map<String, Object>> indDimList, String compType, String date, String orgCode){
this.indDimList = indDimList;
this.compType = compType;
this.date = date;
this.orgCode = orgCode;
}
@Override
public List<Map<String, Object>> call() {
//数据查询
List<Map<String, Object>> relist = Lists.newArrayList();
try{
for(Map<String, Object> map : this.indDimList){
Map<String, Object> indDimInfoMap = (Map<String, Object>) map.get("indDimInfo");
boolean isCollect = (boolean) map.get("isCollect");
indDimInfoMap.put("indDimInfo", null);
//参数准备
JSONArray jsonArray = new JSONArray();
JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(indDimInfoMap));
jsonArray.add(jsonObject);
//查询数据
Map<String, Object> reMap = queryComponentData(jsonArray, date, compType, orgCode, isCollect,null);
relist.add(reMap);
}
//执行等待
}catch (Exception ex){
logger.error("EngineServiceImpl.IndDataThread.run:" + ex.getMessage());
}
return relist;
}
}