如何防止春季的时间表重叠?

2022-09-01 00:15:54
@Scheduled(fixedDelay = 5000)
public void myJob() {
     Thread.sleep(12000);
}

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


答案 1

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

此外,即使您将默认的执行程序替换为基于线程池的执行程序,这些执行程序通常也会延迟任务实例的执行,直到先前计划的实例完成。这适用于固定延迟、固定间隔和基于 cron 的调度。例如,此 spring 配置将创建一个 ScheduledThreadPoolExecutor,该执行器使用线程池,但不允许同一计划的并发实例,就像您希望的那样:

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

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

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

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


答案 2

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


推荐