Spring @Scheduled 计时器精度

Spring @Scheduled timer accuracy

我正在使用 spring-boot @Scheduled 注释,固定延迟以毫秒为单位,如 javadoc 中所述:

Execute the annotated method with a fixed period in milliseconds between the end of the last invocation and the start of the next.

代码:

@Scheduled(fixedDelay=1000)
public void task() {
    LOG.info("START: " + System.currentTimeInMillis());
    ....do some work here...
    LOG.info("END: " + System.currentTimeInMillis());
}

有时我得到这样的输出,即上一个任务结束和下一个任务开始之间的时间小于 1000ms 大约 2-30 milliseconds

它是由于某种粒度而正常还是为什么会发生?这个增量值有什么保证吗?

显然无法保证,因为您很可能不在实时系统上。根据 CPU(s) 目前所做的事情,它可能会有所不同。由于 OS 调度调用等原因,在大多数 PC 上实际上很难做类似的事情(除非您可以直接访问 CPU/GPU 但即便如此)

您可以通过多种方式使用 @Scheduled 注释。

根据 documentation:

fixedRate 每 t 毫秒调用一次该方法,但时间延迟是从调用开始时计算的。如果传递了 t ms 并且该方法仍在执行中,那么下一次调用将等待它完成并在第一次调用之后立即调用。尝试将 Thread.sleep(3000) 放入您的方法中。我认为您的方法大约需要 950 毫秒才能完成。

如果你想在完成执行后等待,你可以使用fixedDelay

@Scheduled(fixedDelay=1000) 的工作原理是,它会 运行 每 1000 ms 这个无效方法(如果此任务完成执行 < 1000 ms 或者这将 运行 异步)。如果 > 1000ms 则执行任务将进入所使用的 Executor 服务中的任务队列。 没有任务结束和下一个任务开始的联系,但与任务开始和下一个任务开始.