SpringBoot使用@Async实现异步

一、什么是异步

  • 异步调用指的是只是发送的调用的指令,调用者无需等待被调用方法完全执行完毕。指令发出后则继续执行下面的流程。

二、异步的使用场景

  • 用户抽奖时中奖的奖品会异步发放

三、@Async介绍

  • 在Spring中,基于@Async标注的方法,称之为异步方法;这些方法将在执行的时候,将会在独立的线程中被执行,调用者无需等待它的完成,即可继续其他的操作。
  • 首先在启动类上加上 @EnableAsync 注解
  • 在需要异步的方法上加上 @Async 注解,表示此方法是一个异步方法
  • @Async也可使用自定义线程池
    • @Async("自定义线程池bean name")

四、@Async实现异步

1. 在SpringBoot启动类上添加开启异步注解

@EnableAsync  -> 异步注解
@SpringBootApplication
public class DrawApplication {
    public static void main(String[] args) {
        SpringApplication.run(DrawApplication.class, args);
    }
}

 2. 在要实现异步的方法上添加注解

  • 不使用自定义线程池实现
@Async
public void add(int num1 , int num2) {
    ...要执行代码
}

  • 使用自定义线程池实现,需要写一个自定义线程池配置类
@Async("asyncExecutor")
public void add(int num1 , int num2) {
    ...要执行代码
}
  • 自定义线程池配置类
    @Configuration
    public class AsyncConfig {
    
        private static final int MAX_POOL_SIZE = 50;//最大线程数
        public static final int CORE_POOL_SIZE = 20;//核心线程数
    
        @Bean("asyncExecutor")
        public AsyncTaskExecutor asyncTaskExecutor() {
            ThreadPoolTaskExecutor async = new ThreadPoolTaskExecutor();
    
            async.setMaxPoolSize(MAX_POOL_SIZE);
            async.setCorePoolSize(CORE_POOL_SIZE);
            async.setThreadNamePrefix("async-thread");//线程名称
            async.setWaitForTasksToCompleteOnShutdown(false);
            async.setQueueCapacity(100);//队列容量
    
            //1. 当任务添加到线程池中被拒绝时,它将抛出 RejectedExecutionException 异常
            async.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());//拒绝策略
    
            //2. 当任务添加到线程池中被拒绝时,会在线程池当前正在运行的Thread线程池中处理被拒绝的任务
            //async.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
    
            //3. 当任务添加到线程池中被拒绝时,线程池会放弃等待队列中最旧的未处理任务,然后将被拒绝的任务添加到等待队列中。
            //async.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardOldestPolicy());
    
            //4. 当任务添加到线程池中被拒绝时,线程池将丢弃被拒绝的任务。
            //async.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
            
            return async;
        }
    }

    此时再调用此方法可实现异步调用了。

 五、注意事项

如下方式会使@Async失效

  • 异步方法使用static修饰
  • 异步类没有使用@Component注解(或其他注解)导致spring无法扫描到异步类
  • 异步方法不能与被调用的异步方法在同一个类中,因为无法产生切面
  • 类中需要使用@Autowired或@Resource等注解自动注入,不能自己手动new对象
  • 如果使用SpringBoot框架必须在启动类中增加@EnableAsync注解

你可能感兴趣的:(Springboot,java,spring,线程池)