【SpringBoot】自定义SpringBoot定时任务线程池

问题

多个定时任务设置同时启动时,只有一个定时任务被执行。

原因

ScheduledTaskRegistrar类里有一段这样的代码
jpg
springBoot定时任务默认使用newSingleThreadScheduledExecutor创建线程池,最多只能同时存在一个定时任务线程运行。

解决

方法1:项目启动时注入TaskScheduler的bean,并设置线程池大小(未尝试)

@Bean
public TaskScheduler taskScheduler() {
    ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
    taskScheduler.setPoolSize(50);
    return taskScheduler;
}

方法2:增加springBoot配置

spring.task.scheduling.pool.size=50

根据我的实际使用,发现运行过程中虽然可以成功创建多个线程来运行定时任务了,但是运行结束后通过Jconsole查看线程,线程一直处于未关闭的状态。我的定时任务设定是每个月执行一次,这样的线程池也不符合我的需求。于是便开始尝试使用自定的线程池来创建线程运行定时任务。

解决步骤:

  1. 创建线程池配置类

    @Configuration
    public class TaskPoolConfig implements AsyncConfigurer {
    
        @Override
        @Bean("taskExecutor")
        public Executor getAsyncExecutor(){
            ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
            //线程核心池,每月执行一次,设为0
            taskExecutor.setCorePoolSize(0);
            //线程核心池最大值
            taskExecutor.setMaxPoolSize(50);
            //线程等待队列0
            taskExecutor.setQueueCapacity(0);
            //线程空闲等待时间,超过60秒关闭
            taskExecutor.setKeepAliveSeconds(60);
            //线程前缀
            taskExecutor.setThreadNamePrefix("taskExecutorXFF--");
            taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
            taskExecutor.setAwaitTerminationSeconds(60);
            return taskExecutor;
        }
    }
    
  2. 启动类上添加@EnableAsync注解

  3. 在定时任务方法上添加@Async(“taskExecutor”)注解

    @Scheduled(cron = "0 0 0 1 7/1 ?")  
    @Async("taskExecutor")  
    public void dataUpdate1() {
        ...
    }
    

这样就做到了自定义SpringBoot定时任务运行的线程池