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…