默认情况下,SpringBoot下所有的定时任务都是用同一个线程池中同一个线程去执行的,即单线程执行。
从ScheduledAnnotationBeanPostProcessor类开始。ScheduledTaskRegistrar(定时任务注册类)中的ScheduleTasks中又这样一段判断:
if (this.taskScheduler == null) {
this.localExecutor = Executors.newSingleThreadScheduledExecutor();
this.taskScheduler = new ConcurrentTaskScheduler(this.localExecutor);
}
这就说明如果taskScheduler为空,那么就给定时任务做了一个单线程的线程池,正好在这个类中还有一个设置taskScheduler的方法:
public void setScheduler(Object scheduler) {
Assert.notNull(scheduler, "Scheduler object must not be null");
if (scheduler instanceof TaskScheduler) {
this.taskScheduler = (TaskScheduler) scheduler;
}
else if (scheduler instanceof ScheduledExecutorService) {
this.taskScheduler = new ConcurrentTaskScheduler(((ScheduledExecutorService) scheduler));
}
else {
throw new IllegalArgumentException("Unsupported scheduler type: " + scheduler.getClass());
}
}
这样问题就很简单了,只需用调用这个方法显式的设置一个ScheduledExecutorService就可以达到并发的效果了。要做的仅仅是实现SchedulingConfigurer接口,重写configureTasks方法就OK了;
package com.autoai.car.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
/**
* Created by IntelliJ IDEA 2019.
* User: shingmoyeung.
* Date: 2019/11/21.
* Time: 14:29.
* To change this template use File Or Preferences | Settings | Editor | File and Code Templates.
* File Description: 线程池配置
*/
@Configuration
public class ScheduleConfig implements SchedulingConfigurer {
/**
* 线程池名称前缀
*/
@Value(value = "${schedule.threadname.prefix:car-schedule-pool-}")
private String threadNamePrefix;
/**
* 线程池大小
*/
@Value(value = "${schedule.poolsize:10}")
private int poolSize;
/**
* 所有的定时任务都放在一个线程池中,定时任务启动时使用不同线程
*
* @param scheduledTaskRegistrar {@link ScheduledTaskRegistrar} 对象
*/
@Override
public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
//初始化线程池
ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
threadPoolTaskScheduler.setPoolSize(poolSize);
threadPoolTaskScheduler.setThreadNamePrefix("");
threadPoolTaskScheduler.afterPropertiesSet();
//设置线程池
scheduledTaskRegistrar.setScheduler(threadPoolTaskScheduler);
}
}
或者,注入以下bean
@Bean
public TaskScheduler taskScheduler() {
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.setPoolSize(10);
return scheduler;
}
参考以下文章:
版权声明:本文为CSDN博主「指尖de柔情」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u013456370/article/details/79411952