前段时间需要编写一个关于统计人口不同年龄段的数量,因为数据量比较大,又是大表,所以接口需要改写成同时并行循环操作,其中用到了一个异步多线程FutureTask并行操作,具体的代码如下:
- controller 调用层
public void qryPersonByAge(AreaCode areaCode,NewAreaCode newAreaCode, ModelMap modelMap){
//处理接收实体类
AreaCodeUtil.changeAreaCode(areaCode,newAreaCode);
List<PersonAge> list = new ArrayList<PersonAge>();
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
Calendar calendar = Calendar.getInstance();
//['0-7', '8-13', '14-25', '26-35', '36-45', '46-55', '56-65', '66-75', '>76'] 年龄分布
calendar.setTime(new Date());
String endAge1 = sdf.format(calendar.getTime());
calendar.add(Calendar.YEAR, -7);
String startAge1 = sdf.format(calendar.getTime());
calendar.add(Calendar.YEAR,-6);
String startAge2 = sdf.format(calendar.getTime());
calendar.add(Calendar.YEAR,-12);
String startAge3 = sdf.format(calendar.getTime());
calendar.add(Calendar.YEAR,-10);
String startAge4 = sdf.format(calendar.getTime());
calendar.add(Calendar.YEAR,-10);
String startAge5 = sdf.format(calendar.getTime());
calendar.add(Calendar.YEAR,-10);
String startAge6 = sdf.format(calendar.getTime());
calendar.add(Calendar.YEAR,-10);
String startAge7 = sdf.format(calendar.getTime());
calendar.add(Calendar.YEAR,-10);
String startAge8 = sdf.format(calendar.getTime());
calendar.add(Calendar.YEAR,-100);
String startAge9 = sdf.format(calendar.getTime());
list.add(new PersonAge("0-7",startAge1,endAge1));
list.add(new PersonAge("8-13",startAge2,startAge1));
list.add(new PersonAge("14-25",startAge3,startAge2));
list.add(new PersonAge("26-35",startAge4,startAge3));
list.add(new PersonAge("36-45",startAge5,startAge4));
list.add(new PersonAge("46-55",startAge6,startAge5));
list.add(new PersonAge("56-65",startAge7,startAge6));
list.add(new PersonAge("66-75",startAge8,startAge7));
list.add(new PersonAge(">76",startAge9,startAge8));
//不同年龄循环查询
//String startAge,endAge,ageLabel;
//Map<String,Object> map = new HashMap<String, Object>();
List<Map<String, Object>> personAgeList = new ArrayList<Map<String, Object>>();
/*for(int i =0;i<list.size();i++){
startAge = list.get(i).getStartAge();
endAge = list.get(i).getEndAge();
ageLabel = list.get(i).getAgeLabel();
map = peaceIndexService.qryPersonByAge(newAreaCode.getQxdm(),newAreaCode.getZjdm(),newAreaCode.getCsqdm(),startAge,endAge,ageLabel);
personAgeList.add(map);
}*/
long st = System.currentTimeMillis();
List<FutureTask<Map<String, Object>>> tasks = new ArrayList<FutureTask<Map<String, Object>>>();
for(int i =0;i<list.size();i++){
FutureTask<Map<String, Object>> task = new FutureTask<Map<String, Object>>(new StatTask(newAreaCode.getQxdm(), newAreaCode.getZjdm(), newAreaCode.getCsqdm(), list.get(i).getStartAge(), list.get(i).getEndAge(), list.get(i).getAgeLabel(), peaceIndexService));
ThreadPools.getInstance().getPools().submit(task);
tasks.add(task);
}
for (FutureTask<Map<String, Object>> t : tasks) {
try {
Map<String, Object> m = t.get();
if (m == null || m.isEmpty()) {
continue;
}
personAgeList.add(m);
} catch (Exception e) {
logger.error("--- Failed to get Callable[Future], Caused by : ", e);
}
}
logger.info("--- Cost Time : " + (System.currentTimeMillis() - st) + "ms");
modelMap.addAttribute("personAgeList",personAgeList);
logger.info("年龄人口分布:{}",personAgeList);
}
- StartTask.java 类,多线程启动类
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.Callable;
public class StartTask implements Callable<Map<String, Object>> {
private PeaceIndexService peaceIndexService;
private String areaCodeDc;
private String areaCodeSt;
private String areaCodeCt;
private String startAge;
private String endAge;
private String ageLabel;
public StartTask(String areaCodeDc, String areaCodeSt, String areaCodeCt, String startAge, String endAge, String ageLabel, PeaceIndexService peaceIndexService) {
this.areaCodeDc = areaCodeDc;
this.areaCodeSt = areaCodeSt;
this.areaCodeCt = areaCodeCt;
this.startAge = startAge;
this.endAge = endAge;
this.ageLabel = ageLabel;
this.peaceIndexService = peaceIndexService;
}
@SuppressWarnings("unchecked")
@Override
public Map<String, Object> call() throws Exception {
//包装调用单线程正常接口
Map<String, Object> map = peaceIndexService.qryPersonByAge(areaCodeDc, areaCodeSt, areaCodeCt, startAge, endAge, ageLabel);
return (Map<String, Object>) (map == null ? Collections.emptyMap() : map);
}
}