Is Spring Boot single-threaded or multi-threaded?

Lxlxxx 2022-08-06 12:32:31 阅读数:948

springbootsingle-threadedsinglethreaded

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第4天,点击查看活动详情

前言

我们知道用Spring BootIt is very convenient to build projects,We use it to quickly build projects during development,自带tomcat容器、Startup will also need to be configuredbeanAll loaded into oursSpring容器里面.但是在调用Controller方法的时候,是单线程、Or multi-threaded,Let's study it together today.

执行Controller

First we do it by doing bothController方法,Find the printed log,The execution of these two methods are separate threads,But the created variables are superimposed,因为SpringThe default is to create a singleton mode,So it will lead to thread unsafe.

4ABF2C5E-970D-45EB-8570-0FF05C213A30.png

我们在Çontroller头部加入@Scope,Make it scoped to prototype mode,At this point we execute the method again.

@RequestMapping(“test”)
@Scope(“prototype”)
@RestController
public class TestController {
复制代码

It can be seen that there are still two threads executing,But the operation of our variable is not added by class,but separatelyi++的操作,prove every timereqeust请求都会创建一个bean. 注意️:We must not be there when we write codeÇontroller里面定义常量,Then operate in the method,会有很大的问题,这里只是做演示.

313B2929-F70A-42D2-B795-EB0E8FF40F67.png

由此可见Spring Boot中Controller默认是单例模式,And the execution is multi-threaded.

@Async

Since it was mentioned here,我们就来说下Spring BootA multithreading first principle,Let's take a look at our asynchronous execution annotation [email protected],通过使用注解的方式,In scenarios where we need to execute methods asynchronously,Implement an asynchronous execution. 当然也离不开@EnableAsync这个注解,It is an asynchronous annotation switch.You can see that the proxy mode is used.

6F468EC9-F4F5-4D01-B0B8-7FA40CA5DBD6.png

Traced by looking at the source codeAsyncTaskExecutor 这个接口,As you can see from the name, it is an interface created by a thread pool of asynchronous tasks,继承的TaskExecutor父接口. 35F16DD2-487D-48E8-8616-2506F0C4D7E6.png

可以看到ThreadPoolTaskExecutorThe configuration class for this thread pool,You can see that asynchronous operations are actually done by creating a thread pool,By submitting to the thread pooltask任务,用Future类接收,The execution result of an asynchronous task can be obtained.

72C52829-4D35-4836-8077-E40D81848700.png

F82C6660-8090-497C-981F-59AB0278BC44.png

使用Async

Let's go through a custom thread pool,Then submit our asynchronous task to the thread pool first.

AsyncService异步方法

@Service
public class AsyncService {
private Logger logger = LoggerFactory./getLogger/(TestController.class);
@Async(“taskExecutor”)
public String getAsyncMessage(String message) {
try {
logger.info(“执行异步方法,message is “ + message);
Thread./sleep/(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return message;
}
复制代码

AsyncConfig异步线程池配置

public class AsyncConfig {
@Bean(“taskExecutor”)
public Executor taskExecutor(){
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// 核心线程数:线程池创建时候初始化的线程数
executor.setCorePoolSize(10);
// 最大线程数:线程池最大的线程数,只有在缓冲队列满了之后才会申请超过核心线程数的线程
executor.setMaxPoolSize(20);
// 缓冲队列:用来缓冲执行任务的队列
executor.setQueueCapacity(500);
// 允许线程的空闲时间60秒:当超过了核心线程之外的线程在空闲时间到达之后会被销毁
executor.setKeepAliveSeconds(60);
// 线程池名的前缀:设置好了之后可以方便我们定位处理任务所在的线程池
executor.setThreadNamePrefix(“Async-task-“);
// 缓冲队列满了之后的拒绝策略:由调用线程处理(一般是主线程)
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
复制代码

执行结果,We can see that the async method is submitted via the thread pool we defined,没有按照forCircular sequential commits,Instead, it implements an asynchronous submission.

E6DE8970-61B8-41C0-979A-E089423A0793.png

总结

Spring BootA framework is a framework that can implement multithreading,Not a thread safe framework,We want to make it thread safe,Other components also need to be integrated,Including the use of some thread-safe classes,但是可以说明Spring Boot在执行ControllerThe method is indeed executed in a multi-threaded manner,Include asynchronous methods.

copyright:author[Lxlxxx],Please bring the original link to reprint, thank you. https://en.javamana.com/2022/218/202208061228143135.html