SpringBoot注解Async多次调用就成功一次,是线程池没配,不配置默认可执行的线程数UNBOUNDED_CONCURRENCY是-1,等于没有并发量

源码位置

解决方案一

springboot2.2之前的问题了,后面的版本不配置也是使用的线程池
使用AsyncConfigurer接口,重写getAsyncExecutor可以把注解的默认线程池改为一个ThreadPoolTaskExecutor

@Configuration
@EnableAsync
@SLf4j
public class Asyncconfiguration implements Asyncconfigurer {
    @Bean(name = "defauLtPooLTaskExecutor")
    public ThreadPoolTaskExecutor executor() {
        ThreadPoolTaskExecutor taskExecutor = new ThreadPooLTaskExecutor();
        // 核心线程数
        taskExecutor.setcorePoolsize(2);
        // 线程池维护线程的最大数量,只有在缓冲队列满了之后才会申请超过核心线程数的线程
        taskExecutor.setMaxPoolSize(10); // 缓存队列
        taskExecutor.setQueueCapacity(50);
        // 许的空闲时间,当超过了核心线程出之外的线程在空闲时间到达之后会被销毁
        taskExecutor.setKeepAliveSeconds(200); // 异步方法内部线程名称
        taskExecutor.setThreadNamePrefix("defauLt-");
        /**
         * 当线程池的任务缓存队列已满并且线程池中的线程数目达到mnaximumPooLSize,如果还有任务到来就会采取任务拒绝策略
         * 有四种策略
         */
    }
}

解决方案二

配置自定义线程池

@Configuration
@EnableAsync
public class ThreadPoolConfig {
    @Bean(name = "asyncThreadPoolExecutor")
    public Executor threadPoolExecutor() {
        ThreadPoolTaskExecutor threadPoolExecutor = new ThreadPoolTaskExecutor();
        // 返回可用处理器的Java虚拟机的数量
        int processNum = Runtime.getRuntime().availableProcessors();
        int corePoolSize = (int) (processNum / (1 - 0.2));
        int maxPoolSize = (int) (processNum / (1 - 0.5));
        // 核心池大小
        threadPoolExecutor.setCorePoolSize(corePoolSize);
        // 最大线程数
        threadPoolExecutor.setMaxPoolSize(maxPoolSize);
        // 队列程度
        threadPoolExecutor.setQueueCapacity(400);
        threadPoolExecutor.setThreadPriority(Thread.MAX_PRIORITY);
        threadPoolExecutor.setDaemon(false);
        // 线程空闲时间
        threadPoolExecutor.setKeepAliveSeconds(300);
        // 线程名字前缀
        threadPoolExecutor.setThreadNamePrefix("async-Executor-");
        return threadPoolExecutor;
    }
}
posted @ 2024-10-15 11:51  Journey&Flower  阅读(21)  评论(0)    收藏  举报