2023年7月21日发(作者:)
spring定时任务原理参考⽂章: /post/5b64448af265da0f7f44c201 /post/5e338ebae51d4558864b1ca01、开发中使⽤时要注意的点 (0)spring定时任务执⾏原理实际使⽤的是
JDK ⾃带的
ScheduledExecutorService (1)spring默认使⽤单线程的线程池去执⾏定时任务,所以如果某个任务执⾏时间过长,会导致其他定时任务阻塞⽆法执⾏。 (2)可以开启并⾏调度,springboot中的使⽤⽅式:这种模式每次任务执⾏都会创建⼀个线程去执⾏。@EnableAsync@EnableScheduling@SpringBootApplicationpublic class QuickMediaApplication { public static void main(String[] args) { (, args); } @Scheduled(cron = "0/1 * * * * ?") @Async public void sc1() { n(tThread().getName() + " | sc1 " + tTimeMillis()); }} 风险:如果某个定时任务出现死循环或者执⾏时间过长⽽出发时间较短,会导致线程数量不可控。 (3)最稳妥的处理⽅式:⾃定义任务执⾏的线程池,如下: 普通spring配置:@Beanpublic AsyncTaskExecutor asyncTaskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); eadNamePrefix("task-schedule-"); PoolSize(10); ePoolSize(3); ueCapacity(0); ectedExecutionHandler(new olicy()); return executor;}或@Beanpublic ScheduleExecutorService scheduleExecutorService{ return ScheduleThreadPool(10);
} springboot中配置:=-name-prefix=task-schedule-2、源码分析 通过监听IOC容器初始化事件,扫描所有
Bean 中带有
@Scheduled 注解的⽅法,然后封装成
Task ⼦类放置到
ScheduledTaskRegistrar中。如果⾃⼰定义了ScheduledExecutorService,会使⽤⾃⼰定义的线程池,否则ScheduledTaskRegistrar#afterPropertiesSet 创建⼀个单线程的定时任务执⾏器ScheduledExecutorService,注⼊到
ConcurrentTaskScheduler中,然后通过
taskScheduler 执⾏定时任务。public class ScheduledAnnotationBeanPostProcessor implements ScheduledTaskHolder, MergedBeanDefinitionPostProcessor, DestructionAwareBeanPostProcessor, Ordered, EmbeddedValueResolverAware, BeanNameAware, BeanFactoryAware, ApplicationContextAware, SmartInitializingSingleton, ApplicationListener, DisposableBean { ................ @Override public void onApplicationEvent(ContextRefreshedEvent event) { if (licationContext() == ationContext) { // Running in an ApplicationContext -> register tasks // giving other ContextRefreshedEvent listeners a chance to perform // their work at the same time (e.g. Spring Batch's job registration). finishRegistration(); } } private void finishRegistration() { if (ler != null) { eduler(ler); } .......................if (ks() && eduler() == null) { (ctory != null, "BeanFactory must be set to find scheduler by type"); try { // Search for kScheduler(resolveSchedulerBean(beanFactory, , false)); } catch (NoUniqueBeanDefinitionException ex) { ("Could not find unique TaskScheduler bean", ex); try { kScheduler(resolveSchedulerBean(beanFactory, , true)); } catch (NoSuchBeanDefinitionException ex2) { if (Enabled()) { ("More than one TaskScheduler bean exists within the context, and " + "none is named 'taskScheduler'. Mark one of them as primary or name it 'taskScheduler' " + "(possibly as an alias); or implement the SchedulingConfigurer interface and call " + "ScheduledTaskRegistrar#setScheduler explicitly within the configureTasks() callback: " + nNamesFound()); } } } catch (NoSuchBeanDefinitionException ex) { ("Could not find default TaskScheduler bean", ex); // Search for ScheduledExecutorService try { eduler(resolveSchedulerBean(beanFactory, , false)); } catch (NoUniqueBeanDefinitionException ex2) { ("Could not find unique ScheduledExecutorService bean", ex2); try { eduler(resolveSchedulerBean(beanFactory, , true)); } catch (NoSuchBeanDefinitionException ex3) { if (Enabled()) { ("More than one ScheduledExecutorService bean exists within the context, and " + "none is named 'taskScheduler'. Mark one of them as primary or name it 'taskScheduler' " + "(possibly as an alias); or implement the SchedulingConfigurer interface and call " + "ScheduledTaskRegistrar#setScheduler explicitly within the configureTasks() callback: " + nNamesFound()); } } } catch (NoSuchBeanDefinitionException ex2) { ("Could not find default ScheduledExecutorService bean", ex2); // Giving up -> falling back to default scheduler within ("No TaskScheduler/ScheduledExecutorService bean found for scheduled processing"); } } } ropertiesSet(); }}if (heduler == null) { xecutor = gleThreadScheduledExecutor(); heduler = new ConcurrentTaskScheduler(xecutor);}
1.
Spring 定时任务执⾏原理实际使⽤的是
JDK ⾃带的
ScheduledExecutorService
发布者:admin,转转请注明出处:http://www.yc00.com/web/1689930608a295244.html
评论列表(0条)