1、绪论
本博客内容较基础,适用于java基础比较薄弱的人群。通过这篇文章可以让你学会简单的创建线程的方法。
在java程序编程过程中,你可能会遇到这种情况:某个程序运行时间很长,假设超过5s吧!这时候让界面卡在某个界面5s+显然是不行的,用户交互不友好。
这个时候你就可能要用到多线程了。新建一个线程,把运行时间长的程序块放进去,其他代码照常运行。这样界面就不会卡在某个地方,只不过刚刚这个程序块需要的数据可能暂时没有获取到。
只是语言描述有点难以理解,下面放代码,通过代码来继续解释。
2、代码
/**
* 获得车流量前三的卡扣,及卡扣车流量
* @return
*/
@RequestMapping(value="/getSumTop3",method=RequestMethod.POST,produces="application/json;charset=utf-8")
@ResponseBody
public R getSumTop3(String startDate,String endDate){
//2018-11-29T23:59 ==》 2018-11-29 23:59
startDate = startDate.replace("T"," ");
endDate = endDate.replace('T',' ');
//把时间封装一下
ArrayList<String> startTime = new ArrayList<String>();
startTime.add(startDate);
ArrayList<String> endTime = new ArrayList<String>();
endTime.add(endDate);
//参数封装到Map里
Map<String, Object> map = new HashMap();
map.put("startDate",startTime);
map.put("endDate",endTime);
JSONObject jsonObject = new JSONObject(map);
String jsonString = jsonObject.toJSONString();
//把参数封装到Task对象中
Task task = new Task();
task.setTaskParam(jsonString);
task.setTaskName("车流量top3");
//把这个task插入到数据库,并且返回taskId
final int taskId = taskService.insert(task);
//根据taskId从数据库读出这三条数据
final String cmd = "spark-submit --master spark://node01:7077 --class com.hpe.traffic.monitor.TrafficSumTop3 /opt/tmp/TrafficSumTop3.jar " + taskId;
new Thread(new Runnable() {
@Override
public void run() {
try {
taskService.executor(taskId, cmd);
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
//上面的操作已经把车流量前三的数据插到数据库了
//接下来,从数据库把值拿出来展示
return R.ok().put("taskId",taskId);
}
上面是我写的一个Controller控制层中的一个方法。
重点是下面这一段:
new Thread(new Runnable() {
@Override
public void run() {
try {
taskService.executor(taskId, cmd);
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
在这段代码中,由于taskService.executor(taskId, cmd);
查询时间比较长(在服务器上查询的几百万条数据,大约40s),于是我直接在这个地方另起一个线程,在线程中执行这段代码,此时其余代码在原线程中正常运行。
此时前台显示的列表肯定是没有数据的,我此时拿到了这个任务taskId的值,然后js中就根据这个taskId每个3s查询一次数据库。这样就实现了异步处理的问题。
如果你实在不懂的话,直接复制上面那一小段代码,稍微改一下就能用!
3、总结
由于项目经验有限,可能处理的方式不太好。有大佬有好的建议可以提出来。共勉!!!