@Scheduled定时任务单线程和多线程
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 二选一**/ @Beanpublic ScheduledExecutorService scheduledThreadPool() {ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(9); return scheduledThreadPool;}@Beanpublic TaskScheduler taskScheduler() {ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();taskScheduler.setPoolSize(9);return taskScheduler;}}