1:默认所有的@Scheduled方法由单线程调度
2:如果需要多线程可以有两种方式去设置线程池
2.1 自定义一个ScheduleConfig,实现SchedulingConfigurer的configureTasks方法
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import java.util.concurrent.Executors;
/**
* 多线程定时任务
*/
@Configuration
public class ScheduleConfig implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
//设定一个长度9的定时任务线程池
taskRegistrar.setScheduler(Executors.newScheduledThreadPool(9));
}
}
2.2 自定义 一个TaskScheduler 或者 ScheduledExecutorService 类的bean, 那为啥是这两个类型的bean呢? 请参考源码:org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor#finishRegistration 的方法;
scheduler在registrar的时候 会先后在beanFactory查找是否有TaskScheduler 和 ScheduledExecutorService 类型的bean; 如果有,则作为执行scheduler的线程池;
所以如果设置@Scheduled 多线程执行 则还可以在xml 配置 TaskScheduler 或ScheduledExecutorService 类型的bean, 因为在registrar是按照类型装配,所以自定义的beanName 无特殊要求, 也可以直接在java类里直接定义一个 如:
import java.util.concurrent.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
@Configuration
public class ScheduledConfig {
/** 以下bean 二选一**/
@Bean
public ScheduledExecutorService scheduledThreadPool() {
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(9);
return scheduledThreadPool;
}
@Bean
public TaskScheduler taskScheduler() {
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.setPoolSize(9);
return taskScheduler;
}
}