Spring Boot 使用WebAsyncTask异步返回结果
在spring boot中(spring mvc)下请求默认都是同步的,一个请求过去到结束都是由一个线程负责的,很多时候为了能够提高吞吐量,需要将一些操作异步化,除了一些耗时的业务逻辑可以异步化,我们的查询接口也是可以做到异步执行。
一个请求到服务上,是用的web容器的线程接收的,比如线程http-nio-8084-exec-1
我们可以使用webasynctask将这个请求分发给一个新的线程去执行,http-nio-8084-exec-1可以去接收其他请求的处理。一旦webasynctask返回数据有了,就会被再次调用并且处理,以异步产生的方式,向请求端返回值。
示例代码如下:
@requestmapping(value="/login", method = requestmethod.get) public webasynctask<modelandview> longtimetask(){ system.out.println("/login被调用 thread id is : " + thread.currentthread().getname()); callable<modelandview> callable = new callable<modelandview>() { public modelandview call() throws exception { thread.sleep(1000); /模拟长时间任务 modelandview mav = new modelandview("login/index"); system.out.println("执行成功 thread id is : " + thread.currentthread().getname()); return mav; } }; return new webasynctask<modelandview>(callable); }
可以看到输出结果如下:
/login被调用 thread id is : http-nio-8084-exec-1
执行成功 thread id is : mvcasync1
在执行业务逻辑之前的线程和具体处理业务逻辑的线程不是同一个,达到了我们的目的。
然后我做了一个并发测试,发现不停的在创建mvcasync1这个线程,我就在想,难道没有用线程池?
通过阅读源码才发现果真如此,webasyncmanager是spring mvc管理async processing的中心类。
默认是使用simpleasynctaskexecutor,这个会为每次请求创建一个新的线程
private asynctaskexecutor taskexecutor = new simpleasynctaskexecutor(this.getclass().getsimplename());
如果说任务指定了executor,就用任务指定的,没有就用默认的simpleasynctaskexecutor
asynctaskexecutor executor = webasynctask.getexecutor(); if (executor != null) { this.taskexecutor = executor; }
我们可以配置async 的线程池,不需要为每个任务单独指定
通过configurer.settaskexecutor(threadpooltaskexecutor());来指定
import org.springframework.context.annotation.bean; import org.springframework.context.annotation.configuration; import org.springframework.scheduling.concurrent.threadpooltaskexecutor; import org.springframework.web.context.request.async.timeoutcallableprocessinginterceptor; import org.springframework.web.servlet.config.annotation.asyncsupportconfigurer; import org.springframework.web.servlet.config.annotation.webmvcconfigurationsupport; @configuration public class webmvcconfig extends webmvcconfigurationsupport { @override public void configureasyncsupport(final asyncsupportconfigurer configurer) { configurer.setdefaulttimeout(60 * 1000l); configurer.registercallableinterceptors(timeoutinterceptor()); configurer.settaskexecutor(threadpooltaskexecutor()); } @bean public timeoutcallableprocessinginterceptor timeoutinterceptor() { return new timeoutcallableprocessinginterceptor(); } @bean public threadpooltaskexecutor threadpooltaskexecutor() { threadpooltaskexecutor t = new threadpooltaskexecutor(); t.setcorepoolsize(10); t.setmaxpoolsize(50); t.setthreadnameprefix("yjh"); return t; } }
配置完之后就可以看到输出的线程名称是yjh开头的了,而且也不会一直创建新的线程
可以看到输出结果如下:
/login被调用 thread id is : http-nio-8084-exec-1 执行成功 thread id is : yjh1
总结
以上所述是小编给大家介绍的spring boot 使用webasynctask异步返回结果,希望对大家有所帮助
上一篇: Spring Boot 2.0 设置网站默认首页的实现代码
下一篇: CAD怎么给图纸标注断面符号?
推荐阅读
-
详解Spring/Spring boot异步任务编程WebAsyncTask
-
详解Spring/Spring boot异步任务编程WebAsyncTask
-
spring boot使用自定义配置的线程池执行Async异步任务
-
Spring Boot利用@Async异步调用:使用Future及定义超时详解
-
spring boot使用自定义配置的线程池执行Async异步任务
-
spring boot 使用Aop通知打印控制器请求报文和返回报文问题
-
Spring Boot利用@Async异步调用:使用Future及定义超时详解
-
Spring Boot 使用WebAsyncTask异步返回结果
-
spring boot 使用Aop通知打印控制器请求报文和返回报文问题
-
[Spring Boot]使用自定义注解统一请求返回值