Spring @Async注解的使用

Spring @Async注解的使用

Spring的@Async注解的作用是让被标记的方案异步执行

前提条件:

  • 启动类或配置类上加入@EnableAsync注解;
  • 需要在异步执行的方案必须是被Spring管理的JavaBean中;
  • 需要异步执行的方法上必须加入@Async注解;

适用场景:

  • 日志;
  • 异步执行代码段;

需要注意的点:

  • 因为Async是基于AOP实现的,调用本类中加入Async的其他方法, 不生效;

QuickStarter

在启动类加入@EnableAsync注解后,创建两个方法用于验证

@Service
public class TestService {

    @Async@SneakyThrows
    public void testSync() {
        TimeUnit.SECONDS.sleep(5);
        System.out.println("testSync");
    }

    @SneakyThrows
    public void testCommon() {
        TimeUnit.SECONDS.sleep(5);
        System.out.println("testCommon");
    }

}

Controller

    @GetMapping("/sync")
    public String sync(){
        testService.testSync();
        return "sync";
    }

    @GetMapping("/common")
    public String common(){
        testService.testCommon();
        return "common";
    }

分别调用两个接口,发现/common会阻塞五秒后返回结果;/sync则会立即返回。

线程池问题

默认使用Spring创建ThreadPoolTaskExecutor。

默认核心线程数:8,

最大线程数:Integet.MAX_VALUE,

队列使用LinkedBlockingQueue,

容量是:Integet.MAX_VALUE,

空闲线程保留时间:60s,

线程池拒绝策略:AbortPolicy。

问题:并发情况下,会无无限建线程

解决线程池问题

自定义配置参数

spring:
  task:
    execution:
      pool:
        max-size: 6
        core-size: 3
        keep-alive: 3s
        queue-capacity: 1000
      thread-name-prefix: name

编写自定义线程配置类

@Configuration
@Data
public class ExecutorConfig{
 
    /**
     * 核心线程
     */
    private int corePoolSize;
 
    /**
     * 最大线程
     */
    private int maxPoolSize;
 
    /**
     * 队列容量
     */
    private int queueCapacity;
 
    /**
     * 保持时间
     */
    private int keepAliveSeconds;
 
    /**
     * 名称前缀
     */
    private String preFix;
 
    @Bean
    public Executor myExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(corePoolSize);
        executor.setMaxPoolSize(maxPoolSize);
        executor.setQueueCapacity(queueCapacity);
        executor.setKeepAliveSeconds(keepAliveSeconds);
        executor.setThreadNamePrefix(preFix);
        executor.setRejectedExecutionHandler( new ThreadPoolExecutor.AbortPolicy());
        executor.initialize();
        return executor;
    }
}

参考:

@Async 的使用

Spring中异步注解@Async的使用、原理及使用时可能导致的问题

posted @ 2022-05-24 00:08  张瑞丰  阅读(856)  评论(0编辑  收藏  举报