如何防止Spring中重叠的时间表?

时间:2014-06-04 09:04:05

标签: java spring spring-scheduled

@Scheduled(fixedDelay = 5000)
public void myJob() {
     Thread.sleep(12000);
}

如果上一个例程尚未完成,如何阻止此弹出作业运行?

2 个答案:

答案 0 :(得分:61)

默认情况下,spring使用单线程Executor。所以没有两个@Scheduled任务会重叠。即使两个完全不相关的类中的@Scheduled方法也不会重叠,因为只有一个线程来执行所有@Scheduled任务。

此外,即使您使用基于线程池的执行程序替换默认的Executor,这些执行程序通常也会延迟任务实例的执行,直到先前计划的实例完成为止。对于基于 fixedDelay,fixedInterval和cron 的计划,这是正确的。例如,这个spring配置将创建一个使用线程池的 ScheduledThreadPoolExecutor ,但是不允许同一个时间表的并发实例:

@Configuration
@EnableScheduling
...
public class MySpringJavaConfig {
    @Bean(destroyMethod = "shutdown")
    public Executor taskScheduler() {
        return Executors.newScheduledThreadPool(5);
    }
    ...
}

这里是javadoc for ScheduledThreadPoolExecutor::scheduleAtFixedRate,它指定:

  

如果执行此任务的时间超过其周期,则后续执行可能会延迟,但不会同时执行。

注意:此功能不适用于 @Async任务。 spring将根据需要创建尽可能多的并发实例(如果池中有足够的线程)。

答案 1 :(得分:26)

使用fixedDelay,期间是在完成工作后测量的,所以不用担心。