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 = RequestMethod.GET)public WebAsyncTask<ModelAndView> longTimeTask(){ System.out.println("/login is called thread id is : " + Thread.currentThread().getName()); Callable<ModelAndView> callable = new Callable<ModelAndView>() { public ModelAndView call() throws Exception { Thread.sleep(1000); /Simulate long-term tasks ModelAndView mav = new ModelAndView("login/index"); System.out.println("Execution successful thread id is : " + Thread.currentThread().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 successfully thread id is: MvcAsync1
The thread before executing the business logic and the thread that specifically deals with the business logic are not the same, 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(this.getClass().getSimpleName());
If the task specifies an executor, use the task specifies it. If it doesn't, use the default SimpleAsyncTaskExecutor
AsyncTaskExecutor executor = webAsyncTask.getExecutor();if (executor != null) { this.taskExecutor = executor;}We can configure async's thread pool without specifying it separately for each task
Specify by 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;@Configurationpublic class WebMvcConfig extends WebMvcConfigurationSupport { @Override public void configureAsyncSupport(final AsyncSupportConfigurer configure) { 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; }}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:
/login is called thread id is: http-nio-8084-exec-1 execution successfully thread id is: YJH1
Summarize
The above is what the editor introduced to Spring Boot uses WebAsyncTask to return 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 to Wulin.com website!