In Spring Boot (Spring MVC), requests are synchronized by default. A thread is responsible for the past and end of a request. In many cases, in order to improve throughput, some operations need to be asynchronized. In addition to some time-consuming business logic that can be asynchronized, our query interface can also be executed asynchronously.
A request to the service is received by a thread from a web container, such as the thread http-nio-8084-exec-1
We can use WebAsyncTask to distribute this request to a new thread for execution, and http-nio-8084-exec-1 can receive processing of other requests. Once the WebAsyncTask returns data, it will be called and processed again, and the value will be returned to the requesting side in an asynchronous manner.
The sample code is as follows:
@RequestMapping(value="/login", method = ) public WebAsyncTask<ModelAndView> longTimeTask(){ ("/login is called thread id is: " + ().getName()); Callable<ModelAndView> callable = new Callable<ModelAndView>() { public ModelAndView call() throws Exception { (1000); /Simulate long-term tasks ModelAndView mav = new ModelAndView("login/index"); ("Execution successful thread id is : " + ().getName()); return mav; } }; return new WebAsyncTask<ModelAndView>(callable); }
You can see the output result as follows:
/login is called thread id is: http-nio-8084-exec-1
Execution successful thread id is: MvcAsync1
The thread before executing the business logic is not the same as the thread that specifically deals with the business logic, which achieves our goal.
Then I did a concurrent test and found that I was constantly creating the MvcAsync1 thread. I was thinking, isn't the thread pool used?
After reading the source code, I found that this is true. WebAsyncManager is the central class for Spring MVC to manage async processing.
The default is to use SimpleAsyncTaskExecutor, which will create a new thread for each request.
private AsyncTaskExecutor taskExecutor = new SimpleAsyncTaskExecutor(().getSimpleName());
If the task specifies an executor, use the task specifies it. If it doesn't, use the default SimpleAsyncTaskExecutor
AsyncTaskExecutor executor = (); if (executor != null) { = executor; }
We can configure async's thread pool without specifying it separately for each task
Specify by (threadPoolTaskExecutor());
import ; import ; import ; import ; import ; import ; @Configuration public class WebMvcConfig extends WebMvcConfigurationSupport { @Override public void configureAsyncSupport(final AsyncSupportConfigurer configurer) { (60 * 1000L); (timeoutInterceptor()); (threadPoolTaskExecutor()); } @Bean public TimeoutCallableProcessingInterceptor timeoutInterceptor() { return new TimeoutCallableProcessingInterceptor(); } @Bean public ThreadPoolTaskExecutor threadPoolTaskExecutor() { ThreadPoolTaskExecutor t = new ThreadPoolTaskExecutor(); (10); (50); ("YJH"); return t; } }
After configuration, you can see that the output thread name starts with YJH, and new threads will not be created all the time.
You can see the output result as follows:
/loginBeing called thread id is : http-nio-8084-exec-1 Execution successfully thread id is : YJH1
Summarize
The above is the Spring Boot introduced by the editor to you using WebAsyncTask to return the results asynchronously. I hope it will be helpful to everyone. If you have any questions, please leave me a message and the editor will reply to everyone in time. Thank you very much for your support for my website!