SpringBoot 多线程

关于SpringBoot中多线程的两个注解:
@Async是spring为了方便开发人员进行异步调用而出现的。在方法上加入这个注解,spring会从线程池中获取一个新的线程来执行方法,实现异步调用
@EnableAsync表示开启对异步任务的支持,可以放在SpringBoot的启动类上,也可以放在自定义的配置上。

一:最简单的使用

在springBoot项目中,直接在启动类上加上@EnableAsync,然后在service层的方法上加上@Async,那么当controller调用该方法的时候,就会在主线程外自动新建线程执行该方法。

1.springboot启动类开启异步支持

在springboot项目中,直接在启动类上加上@EnableAsync,然后在service层方法上对于需要异步调用的方法加上@Async,那么当controller层调用这个方法的时候,就会在主线程外自动新建新建线程执行该方法

@EnableAsync//开启异步任务支持
@SpringBootApplication
public class ThreadDemoApplication{
public static void main(String[] args){
SpringApplication.run(ThreadDemoApplication.class,args);
}
}

2、在service中编写测试方法

@Service
public class MutiThreadTest {
@Async
public void add() throws InterruptedException {
for (int i=0;i<=100;i++){
System.out.println(Thread.currentThread().getName()+":"+LocalDateTime.now().toLocalTime());
Thread.sleep(1000);
}
}
@Async
public void sub() throws InterruptedException {
for (int i=0;i<100;i++){
System.out.println(Thread.currentThread().getName()+":"+ LocalDateTime.now().toLocalTime());
Thread.sleep(2000);
}
}
}

编写测试类

@Component
public class TestScheduleApplication implements ApplicationRunner {
@Autowired
MutiThreadTest mutiThreadTest;
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println(Thread.currentThread().getName());
// Thread.sleep(10000);
// System.out.println("sleep结束");
mutiThreadTest.sub();
mutiThreadTest.add();
}
}

如果没有自定义线程池@Async默认的线程池是SimpleAsyncTaskExecutor

三.自定义线程池来使用@Async

1、新建一个线程池配置类,在配置类上加@EnableAsync,不用在启动类上加,可以配置不同的线程池,用bean的name做区分

@Configuration //让spring扫描到
@EnableAsync
public class ThreadConfig {
@Bean(name = "pool1")
public Executor createExecutor(){
ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
threadPoolTaskExecutor.setCorePoolSize(1);//核心线程数(默认线程数)
threadPoolTaskExecutor.setMaxPoolSize(5);//最大线程数
threadPoolTaskExecutor.setKeepAliveSeconds(60);//允许线程空闲时间(单位:默认为秒)
threadPoolTaskExecutor.setQueueCapacity(200);//缓冲队列数
threadPoolTaskExecutor.setThreadNamePrefix("Thread-0");//线程池名前缀
//线程池对拒绝任务的处理策略
threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
return threadPoolTaskExecutor;
}
@Bean(name = "pool2")
public ThreadPoolTaskExecutor createExecutor2(){
ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
threadPoolTaskExecutor.setCorePoolSize(1);//核心线程数(默认线程数)
threadPoolTaskExecutor.setCorePoolSize(5);//最大线程数
threadPoolTaskExecutor.setKeepAliveSeconds(60);//允许线程空闲时间(单位:默认为秒)
threadPoolTaskExecutor.setQueueCapacity(200);//缓冲队列数
threadPoolTaskExecutor.setThreadNamePrefix("Thread-1");//线程池名前缀
//线程池对拒绝任务的处理策略
threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
return threadPoolTaskExecutor;
}
}

2、@Async的使用一样是在service层的方法上加,如果配置了多个线程池,可以用@Async("name"),那么表示线程池的@Bean的name,来指定用哪个线程池来处理
假如只配置了一个线程池,直接用@Async就会用自定义的线程池执行
加入配置了多个线程池,用@Async没有指定用哪个线程池,会默认的SimpleAsyncTaskExecutor来处理

/**
* @Author: LS
* @Date: 2022 - 08 - 18 - 9:22
* @Description: 自定义多线程线程池
* @version: 1.0
*/
@Component
public class MutiThreadTest1 {
@Async("pool1")
public void method1() throws InterruptedException {
for (int i = 0;i<100;i++){
System.out.println(Thread.currentThread().getName()+":"+ LocalDateTime.now().toLocalTime()+"====="+i);
// Thread.sleep(1000);
}
}
@Async("pool2")
public void method2(){
for (int i = 0;i<100;i++){
System.out.println(Thread.currentThread().getName()+":"+LocalDateTime.now().toLocalTime()+"----"+i);
}
}
@Async("pool1")
public void method3(){
for (int i = 0;i<100;i++){
System.out.println(Thread.currentThread().getName()+":"+ LocalDateTime.now().toLocalTime()+"////"+i);
}
}
}

3、测试类

@Component
public class TestScheduleApplication implements ApplicationRunner {
@Autowired
MutiThreadTest mutiThreadTest;
@Autowired
MutiThreadTest1 mutiThreadTest1;
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println(Thread.currentThread().getName());
// Thread.sleep(10000);
// System.out.println("sleep结束");
// mutiThreadTest.sub();
// mutiThreadTest.add();
mutiThreadTest1.method1();
mutiThreadTest1.method2();
mutiThreadTest1.method3();
}
}
posted @   生活的样子就该是那样  阅读(4867)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示