文章目录
SpringBoot实现多线程
- SpringBoot通过
任务执行器TaskExecutor
来实现多线程和并发编程。 - 使用
TreadPoolTaskExecutor
可实现一个基于线程池的TaskExecutor
。 - 实际开发任务
一般是非阻碍的,即异步的
,所以我们要在配置类中通过@EnableAsync
开启对异步任务
的支持,并通过在实际执行的Bean中的方法使用@Async注解
来声明这是一个异步任务
。
0. 同步和异步
同步交互
:指发送一个请求,需要等待返回
,然后才能够发送下一个请求,有个等待过程;异步交互
:指发送一个请求,不需要等待返回
,随时可以再发送下一个请求,即不需要等待。
区别:一个需要等待,一个不需要等待。
在部分情况下
,我们的项目开发中都会优先
选择不需要等待的异步交互方式
。
1. 引入 Maven 依赖
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId><version>2.4.4</version></dependency></dependencies>
2. 异步执行的配置类 AsyncConfig
package com.melodyjerry.thread;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.scheduling.annotation.AsyncConfigurer;import org.springframework.scheduling.annotation.EnableAsync;import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;import java.util.concurrent.Executor;/**
* @classname AsyncConfig
* @description 开启异步执行的配置类
*/@Configuration@EnableAsync//开启异步执行@ComponentScan("com.melodyjerry.thread")publicclassAsyncConfigimplementsAsyncConfigurer{@Overridepublic ExecutorgetAsyncExecutor(){
ThreadPoolTaskExecutor threadPoolTaskExecutor=newThreadPoolTaskExecutor();//线程池中的线程的名称前缀
threadPoolTaskExecutor.setThreadNamePrefix("SpringBoot线程池的前缀-");//线程池的核心线程数大小
threadPoolTaskExecutor.setCorePoolSize(4);//线程池的最大线程数
threadPoolTaskExecutor.setMaxPoolSize(8);//等待队列的大小
threadPoolTaskExecutor.setQueueCapacity(25);//执行初始化
threadPoolTaskExecutor.initialize();return threadPoolTaskExecutor;}}
3. 异步任务的执行类
package com.melodyjerry.thread;import org.springframework.scheduling.annotation.Async;import org.springframework.stereotype.Service;/**
* @classname AsyncTaskService
* @description 异步任务的执行类
*/@ServicepublicclassAsyncTaskService{@Async//异步方法publicvoidexecuteAsyncTask(Integer i){
System.out.println("执行异步任务: "+i);}@Async//异步方法publicvoidexecuteAsyncTaskPlus(Integer i){
System.out.println("执行异步任务+1: "+(i+1));}}
@Async
注解表明该方法是个异步方法
。从Async注解接口可以看到,
Target
即可以在方法
也可以在类型
上,如果注解在类型上,表明该类所有的方法都是异步方法。
4. 测试效果 TestThreadApplication
package com.melodyjerry.thread;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.context.ConfigurableApplicationContext;/**
* @classname TestThreadApplication
* @description 测试异步任务
*/@SpringBootApplicationpublicclassTestThreadApplication{publicstaticvoidmain(String[] args){
ConfigurableApplicationContext context= SpringApplication.run(TestThreadApplication.class, args);
AsyncTaskService asyncTaskService= context.getBean(AsyncTaskService.class);for(int i=0; i<10; i++){
asyncTaskService.executeAsyncTask(i);
asyncTaskService.executeAsyncTaskPlus(i);}
System.out.println("This Program has Begun successfully");}}
This Program has Begun successfully
执行异步任务: 0
执行异步任务: 2
执行异步任务+1: 1
执行异步任务+1: 3
执行异步任务: 3
执行异步任务: 4
执行异步任务+1: 5
执行异步任务: 5
执行异步任务+1: 6
执行异步任务+1: 2
执行异步任务: 6
执行异步任务+1: 4
执行异步任务: 7
执行异步任务: 8
执行异步任务+1: 9
执行异步任务: 9
执行异步任务+1: 10
执行异步任务+1: 7
执行异步任务+1: 8
执行异步任务: 1