【WebAsyncTask 异步线程调用】
异步模式处理步骤概述如下:
- 当Controller返回值是WebAsyncTask的时候
- Spring就会将Callable交给TaskExecutor去处理(一个隔离的线程池)
- 与此同时将DispatcherServlet里的拦截器、Filter等等都马上退出主线程,但是response仍然保持打开的状态
- Callable线程处理完成后
示例:
@GetMapping("/asyncExcuteWork/{uuid}")
@ResponseBody
public WebAsyncTask<Boolean> asyncExcuteWork(@PathVariable("uuid") String workuuid) {
WebAsyncTask<Boolean> webAsyncTask = new WebAsyncTask<>(3 * 60 * 1000, new ExcuteWorkCallable(workuuid,workService));
return webAsyncTask;
}
public class ExcuteWorkCallable implements Callable<Boolean> {
private String uuid;
private WorkService workService;
public ExcuteWorkCallable(String workuuid, WorkService workService) {
this.uuid = workuuid;
this.workService = workService;
}
@Override
public Boolean call() throws Exception {
workService.excuteWork(uuid);
return true;
}
}
WebAsyncTask实现异步超时
每一个处理请求的线程会调用startCallableProcessing方法,在该方法内,向线程池提交task, 并将获得的future对象 ,设置到一个new CallableInterceporChain()对象中,用于超时中断该线程。通过对asyncWebRequest设置超时回调(传入匿名内部类对象),将CallableInterceporChaing关联到请求中来,最后在超时回调中执行
超时回调是如何触发的
tomcat会启动一个超时监听守护进程,监听所有异步的超时,当监听到超时以后,会把对应的socket状态设置为time_out,同时socket状态的变化,又会触发tomcat监听进程poller,执行process方法
SIcap中实现超时部分:
//同步等待执行结果
Boolean stateFlag = true;
Map<String, List<AutoMateOperationResult>> resultMap = new HashMap<>();
CountDownLatch lock = new CountDownLatch(workStepitemFiles.size());
//启动阻塞线程等待执行结果
for (Map<String, String> workStep : workSteps) {
然后触发listener的超时事件最后这个Listener就是AsyncWebRequest, 调用onTimeout方法
