Spring @Scheduled cron定时任务是否等待上一次执行完成再运行
Spring @Scheduled 定时任务行为说明
以下是示例定时任务代码:
@Scheduled(cron = "0 * * * * *") public void doSomething() { ... }
相关问题的准确结论如下:
- 问题1:默认配置下,上一次任务未执行完成时不会启动新的任务实例。Spring调度模块默认初始化的任务线程池核心线程数为1,所有被
@Scheduled标注的任务默认共用这一个工作线程,上一次任务未执行完成会持续占用线程,新的调度触发节点没有可用线程分配,自然无法启动新的任务实例。 - 问题2:默认配置本身就支持同任务串行执行。如果你手动修改过调度线程池配置、将核心线程数设置为大于1的值,要保证单任务必须等上一次执行完成再启动下一次,只需要在定时任务方法(或方法所在类)上添加
@DisallowConcurrentExecution注解即可。该注解会针对单个任务定义做并发拦截,不受线程池大小影响,也不会阻塞其他独立定时任务执行,比全局把线程池设为1的方案更灵活。 - 问题3:你通过
Thread.sleep()模拟长任务观测到的“等待上一次执行完成再启动新任务”的现象,完全符合Spring框架默认逻辑,测试观测结果准确。默认单工作线程的调度逻辑下,只要任务未执行结束释放线程,就不会分配线程执行同任务的新调度请求。 - 问题4:默认配置下cron任务会直接跳过所有错过的调度时间,等待下一个匹配cron规则的时间节点、且有可用工作线程时才执行,不会在上一次任务执行完成后立刻补跑错过的任务。以上述每分钟0秒触发的cron规则为例:如果0分0秒启动的任务耗时2分30秒才执行完成,那么0分0秒之后到2分0秒之间的所有触发节点都会被直接跳过,下一次任务执行时间为3分0秒,不会在2分30秒任务结束时立刻补跑之前错过的调度。
补充说明:如果需要实现错过任务的补跑逻辑,需要自定义调度器的misfire处理策略,默认策略为不补跑。
内容的提问来源于stack exchange,提问作者Wes
相关产品推荐
相关产品推荐

