主线程等待多个子线程执行结束继续执行
场景:因业务需要,前台要根据清册列循环请求每个清册中对应第三方数据,并请求结束后刷新清册,显示请求结果。
思路:根据清册key,循环调用接口,并将请求结果保存到数据库中,全部请求结束后刷新清册查询;
实际问题:
实际中 由于清册数据量大配合原有的单线程的请求,会导致前台连接超时,页面无法刷新;
现将 controller层循环请求部分变为多线程请求,并在所有子线程请求结果完成后,返回前台,相应执行刷新清册的请求。
代码:
js代码:
更具清册行循环,将请求参数以 逗号拼接:
for(var i = 0; i < data_plcx.length-1; i++){
if(data_plcx[i].fszt != 0){
continue;
}
ret++;
xingming_plcx += data_plcx[i].xingming+",";
id_plcx += data_plcx[i].id+",";
qzhm_plcx += data_plcx[i].cqzh+",";
}
controller代码(只写出核心部分):
@RequestMapping(value="/findinfo",method=RequestMethod.GET)
@ResponseBody
public AjaxResult findinfo(HttpServletRequest params, HttpSession session, HttpServletResponse response)throws Exception {
AjaxResult ar = new AjaxResult();
String OwnerNames = ("".equals(params.getParameter("xingming")) || params.getParameter("xingming") == null) ? " " : params.getParameter("xingming");
Vector<WorkThread> v=new Vector<WorkThread>();
logger.info("=======================主线程开始:总线程数:"+id_y.length);
for(int i=0;i<id_y.length;i++){
//加入子线程
logger.info("======================="+i+"===========子线程开始");
JsonObject json = new JsonObject();
json.addProperty("OwnerName", OwnerName_y[i]);
//定义子线程
WorkThread workThread = new WorkThread();
//传递参数
workThread.init( i,json, httpService);
v.add(workThread);
logger.info("======================="+i+"===========执行中。。。");
}
for(WorkThread t:v){
t.start();//开启子线程
t.join(); //保证子线程所有执行完成后执行主线程
}
logger.info("=======================主线程结束");
}
ar.setSuccess(true);
ar.setMsg("查询结束");
return ar;
}
另定义多线程类:
class WorkThread extends Thread {
private final Logger logger = Logger.getLogger(this.getClass());
private int i=0;
private JsonObject j ;
private HttpService httpService;
public void update_info(Gjzf_bdcplcx updateBean){
try{
//执行查询结果保存到数据库的代码
}catch (Exception e) {
e.printStackTrace();
}
}
//实现 调用类 向线程传参
public void init(Integer i,JsonObject j,HttpService httpService) {
this.i=i;
this.j = j;
this.httpService = httpService;
}
public void run() {
logger.info("--------------------"+this.i+"---start");
JsonObject json=new JsonObject();
//获取线程参数
json.addProperty("OwnerName",this.j.get("OwnerName").getAsString() );
try{
//执行请求第三方接口
//将接口返回数据 调用 update_info 保存到数据库中
}catch (Exception e) {
e.printStackTrace();
}
j.addProperty("msg", this.i+"子线程执行完成");
logger.info("--------------------"+this.i+"---end");
}
}