1.如果没有在TaskScheduler中指定多个线程,默认线程池中只有一个线程执行调度器,多个调度任务默认是不能并发执行
2.单线程的前提下,cron表达式相同,同一时间只有一个调度器会执行.调度器顺序执行,如果前面的被阻塞/抛出异常,后面的调度器无法执行
3.创建TaskScheduler实例,指定线程数量
4.同一个任务顺序执行,只有当前次执行完,才会执行下一次
1)通过输出的线程名称,说明只有一个线程存在。当线程阻塞,或者抛出异常时,后续的调度器无法执行
2)当在TaskScheduler中指定多个线程后,则不会出现上述情况
@Configuration
public class MyScheduled {
@Scheduled(cron = "0/5 * * * * ?")
public void first() throws InterruptedException {
System.out.println("当前时间:"+ LocalDateTime.now() +"--first--"
+"当前线程:"+Thread.currentThread().getName());
//try {
int i = 1/0;
Thread.sleep(2000);
/* } catch (Exception e) {
e.printStackTrace();
}*/
}
@Scheduled(cron = "0/5 * * * * ?")
public void second() {
System.out.println("当前时间:"+ LocalDateTime.now() +"--second--"
+"当前线程:"+Thread.currentThread().getName());
try {
Thread.sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
}
@Bean
public TaskScheduler taskScheduler() {
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.setPoolSize(10);
return taskScheduler;
}
}
原理分析:
1.查看@Scheduled源码,只是组合注解,并没有引入其他组件,或者方法,不需要过多分析
2.查看@EnableScheduling源码,引入了@Import({SchedulingConfiguration.class})
继续看SchedulingConfiguration的源码,其中生成了ScheduledAnnotationBeanPostProcessor实例,通过看方法调用栈,找到finishRegistration()。
springboot启动时打印日志,....... --- [ main] o.s.s.c.ThreadPoolTaskScheduler : Initializing ExecutorService 'taskScheduler' 1)通过断点和源码分析得知
springboot启动过程中会生成一个ThreadPoolTaskScheduler实例,放入到容器中,其中poolSize=1,如果我们配置了TaskScheduler,则会对实例进行覆盖
- 分析finishRegistration()方法,首先会去容器中找SchedulingConfigurer的实例,我们可以自定义一个类去实现SchedulingConfigurer接口,并重写方法,然后指定TaskScheduler
- 如果没有实现接口,就会按照类型在容器中查找TaskScheduler实例,如果有多个,会按照(taskScheduler)名字查找
- 如果没有找到TaskScheduler类型的bean,则按照类型ScheduledExecutorService查找,如果有多个按照名称(taskScheduler)查找
- 如果都没有,则使用Executors.newSingleThreadScheduledExecutor(),创建只有一个线程的线程池
- 代码分析基于springboot 2.2.9
https://blog.csdn.net/a718515...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。