【@EnableAsync实现异步任务,简单用法】

1、在启动类上加@EnableAsync注解

@EnableScheduling//开启定时任务
@EnableAsync//开启异步任务的支持
@SpringBootApplication
public class TasktestApplication {

    public static void main(String[] args) {
        SpringApplication.run(TasktestApplication.class, args);
    }

}

2、在需要实现异步的方法上加@Async(如果加在类上,那么类中全部方法都实现异步,建议加载具体需要实现异步的方法上)

@Async
public Integer str1() {
   String str = "1111111111";
   try{
      Thread.sleep(5000);
   }catch (Exception e){
      System.out.println(e.getMessage());
   }
   System.out.println("异步线程"+Thread.currentThread().getName()+Thread.currentThread().getId()+":"+str);
   return 1;     
}                         

3、controller层调用异步方法

@PostMapping("/add")
public Integer add(){
    System.out.println("主线程开始执行:"+Thread.currentThread().getName()+Thread.currentThread().getId());
    asyncService.str1();
    System.out.println("主线程结束执行:"+Thread.currentThread().getName()+Thread.currentThread().getId());
    return null;
}

4、测试结果,可以看到先打印了两次输出,主线程先走完,异步方法继续执行,@Async默认的线程池是SimpleAsyncTaskExecutor

主线程开始执行:http-nio-9090-exec-231
主线程结束执行:http-nio-9090-exec-231
异步线程SimpleAsyncTaskExecutor-149:1111111111

5、也可以使用自定义线程池

5.1、新建一个自定义线程池配置类

package com.task.test.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @Date 2022/12/7
 * @Author liuziyan
 * @description
 */
@Configuration//让spring能扫描到
public class ThreadPoolConfig {

    @Bean(name = "pool1")//交给spring管理,起名,可以配置多个线程池
    public Executor createExecutor(){
        ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
        threadPoolTaskExecutor.setCorePoolSize(1);//核心线程数(默认线程数)
        threadPoolTaskExecutor.setMaxPoolSize(5);//最大线程数
        threadPoolTaskExecutor.setKeepAliveSeconds(60);//允许线程空闲时间(单位:默认为秒)
        threadPoolTaskExecutor.setQueueCapacity(200);//缓冲队列数
        threadPoolTaskExecutor.setThreadNamePrefix("lzyThread");//线程池名前缀
        //线程池对拒绝任务的处理策略
        threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
        threadPoolTaskExecutor.initialize();
        return threadPoolTaskExecutor;
    }

    @Bean(name = "pool2")
    public Executor createExecutor2(){
        ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
        threadPoolTaskExecutor.setCorePoolSize(1);
        threadPoolTaskExecutor.setMaxPoolSize(5);
        threadPoolTaskExecutor.setKeepAliveSeconds(60);
        threadPoolTaskExecutor.setQueueCapacity(200);
        threadPoolTaskExecutor.setThreadNamePrefix("lzyThread2");
        threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
        threadPoolTaskExecutor.initialize();
        return threadPoolTaskExecutor;
    }
}

5.2、方法上用到@Async注解需要指定线程池的Bean名字(如果配置了一个线程池,直接用@Async就会用自定义线程池执行,如果有多个线程池配置,需要指定自定义线程池的Bean名字,否则@Async会使用默认的线程池SimpleAsyncTaskExecutor处理)

@Async("pool1")
public Integer str1() {
    String str = "1111111111";
    try{
        Thread.sleep(5000);
    }catch (Exception e){
        System.out.println(e.getMessage());
    }
    System.out.println("异步线程"+Thread.currentThread().getName()+Thread.currentThread().getId()+":"+str);
    return 1;
}

5.3、执行结果,可以看到,线程的名字是自定义线程池配置的名字

主线程开始执行:http-nio-9090-exec-335
主线程结束执行:http-nio-9090-exec-335
异步线程lzyThread151:1111111111

导致注解不生效的原因有几种:

1、异步方法使用static修饰

2、异步方法类没有使用@Service注解(或其他注解)导致spring无法扫描到异步类

3、controller中需要使用@Autowired或@Resource等注解自动注入异步类,不能自己手动new对象

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值