1.如果没有在TaskScheduler中指定多个线程,默认线程池中只有一个线程执行调度器,多个调度工作默认是不能并发执行
2.单线程的前提下,cron表达式雷同,同一时间只有一个调度器会执行.调度器程序执行,如果后面的被阻塞/抛出异样,前面的调度器无奈执行
3.创立TaskScheduler实例,指定线程数量
4.同一个工作程序执行,只有以后次执行完,才会执行下一次
1)通过输入的线程名称,阐明只有一个线程存在。当线程阻塞,或者抛出异样时,后续的调度器无奈执行2)当在TaskScheduler中指定多个线程后,则不会呈现上述情况@Configurationpublic 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...