假设某个请求需要耗费大量的时间,那么,该请求的线程就会一直同步等待该次请求完成,才能被返回线程池,分配给下一个新的请求,这样极大的限制了系统的处理能力.所以我们希望能在controller层的方法中异步执行,另起一个线程去处理耗时任务,让该线程先返回线程池,那么它就可以继续处理下一个请求,从而增加web程序的吞吐量.
得先确保你用的是Servlet 3.0及以上的版本,Spring MVC版本是4以上
确保web.xml中的中添加:
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<async-supported>true</async-supported>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>app</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/spring-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
3 代码
3.1使用DeferredResult
private final int CorePoolSize = 4;
private ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(CorePoolSize);
@RequestMapping(value="/asynctask", method = RequestMethod.GET)
public DeferredResult<ModelAndView> asyncTask(){
final DeferredResult<ModelAndView> deferredResult = new DeferredResult<ModelAndView>();
scheduler.schedule(new Runnable() {
@Override
public void run() {
try {
ModelAndView mav = new ModelAndView("testView");
mav.addObject("result", "jkluio");
deferredResult.setResult(mav);
}catch (Exception e){
e.printStackTrace();
}
}
}, 5, TimeUnit.SECONDS);
return deferredResult;
}
3.2 使用WebAsyncTask
@RequestMapping(value="/asynctask1", method = RequestMethod.GET)
public WebAsyncTask asynctask1(){
Callable<ModelAndView> callable = new Callable<ModelAndView>() {
public ModelAndView call() throws Exception {
Thread.sleep(3000);
ModelAndView mav = new ModelAndView("testView");
mav.addObject("result", "执行成功");
return mav;
}
};
return new WebAsyncTask(callable);
4 新建testView.jsp承接后台返回内容