当工作重叠时,春季@scheduled cron的预期行为是什么?

2022-09-02 01:17:40

我有一个每小时运行一次的工作,我正在使用Spring的@scheduled cron来安排它。

如果作业花费的时间超过一个小时,我从如何防止 Spring 中的重叠计划中了解到,当第一个作业正在运行时,下一个作业不会启动。

但这是否意味着它将在第一份工作完成后开始,或者它是否错过了机会?

如果我有一个需要 10 个小时的作业,那么所有错过的 cron 作业都会排队,然后在 10 小时后第一个作业完成时逐个执行,还是只运行第一个作业?

谢谢!


答案 1

默认情况下,执行是阻塞和单线程的,这意味着它们不会并发运行。如果希望作业同时运行,也可以对方法进行批注。您可能还想看看不同的执行器@Async

如果您使用的示例问题中所示,则下一个作业只会在当前作业结束之后启动,再加上延迟。因此,如果你的工作需要10个小时,而你有一个,下一个工作将在10个小时后5秒开始。fixedDelayfixedDelay5000

如果您使用的是,则下一个计划事件将排队等待运行,但不会跳过,如文档所示fixedRate

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

如果您只是使用 ,则作业将依次排队和执行(类似于 )。你可以用一个简单的方法测试这个(下面是在Groovy中,但也可以使用普通的Java):cronfixedRate

    int i = 0

    @Scheduled(cron = '* * * * * * ')
    void test() {
        if (i < 5)
            Thread.sleep(10000)

        i += 1
        println '------------------------' + i // No values skipped
    }

您会注意到每个数字都是打印的;例如,从未跳过任何周期。


答案 2

和 的行为是不同的。fixedRatecron

重叠的作业排队等待(根据@Igor的上述答案)。fixedRate

将跳过 重叠的作业。cron

示例 Java 代码来演示其差异:

int i = 0;
@Scheduled(fixedRate = 5000)
public void test() throws InterruptedException {
    Date start = new Date();
    if (i < 3) Thread.sleep(10000);
    i++;
    System.out.printf("start %TT, finish %TT, i = %s%n", start, new Date(), i);
}

输出:

start 13:25:30, finish 13:25:40, i = 1
start 13:25:40, finish 13:25:50, i = 2
start 13:25:50, finish 13:26:00, i = 3
start 13:26:00, finish 13:26:00, i = 4
start 13:26:00, finish 13:26:00, i = 5
start 13:26:00, finish 13:26:00, i = 6
start 13:26:00, finish 13:26:00, i = 7
start 13:26:05, finish 13:26:05, i = 8
start 13:26:10, finish 13:26:10, i = 9
start 13:26:15, finish 13:26:15, i = 10

可以看出,重叠的作业将排队,并在前一个作业完成后立即开始,没有5秒的间隔。

但是,如果我们改用,输出将变为:@Scheduled(cron = "*/5 * * ? * *")

start 13:22:10, finish 13:22:20, i = 1
start 13:22:25, finish 13:22:35, i = 2
start 13:22:40, finish 13:22:50, i = 3
start 13:22:55, finish 13:22:55, i = 4
start 13:23:00, finish 13:23:00, i = 5
start 13:23:05, finish 13:23:05, i = 6
start 13:23:10, finish 13:23:10, i = 7
start 13:23:15, finish 13:23:15, i = 8
start 13:23:20, finish 13:23:20, i = 9
start 13:23:25, finish 13:23:25, i = 10

工作之间总是有5秒的间隔。重叠的作业不会排队并被跳过。


推荐