3

我有一个简单的调度程序,用于每 1 秒重复一次任务:

Cancellable task = Akka.system().scheduler().schedule(
        Duration.create(0, TimeUnit.MILLISECONDS),
        Duration.create(1, TimeUnit.SECONDS),
        actor, new TickMsg("Tick", 0, 120)
);

不幸的是,每次通过都迟到了,ticker-duration所以最后演员在 100 毫秒后收到 TickMsg - 好的,这在文档中有所描述,我很清楚:

它不会在准确的时间执行任务,但在每个滴答声中,它都会运行所有过期的东西。

我无法理解的是为什么每次通过都迟到,这实际上意味着每次通过而不是 1000ms 需要 1100ms。结果在 10 次通过后我们有 1 秒的延迟,1 分钟后是 6 秒,1 小时后是 6 分钟等等......

一些解决方案是将重复持续时间设置得更短一些,因此在所需的滴答声中不会迟到,例如一个有效的示例,然后调度程序根据需要重复任务:

Cancellable task = Akka.system().scheduler().schedule(
        Duration.create(0, TimeUnit.MILLISECONDS),
        Duration.create((1000 - tickerDuration/2), TimeUnit.MILLISECONDS),
        actor, new TickMsg("Tick", 0, 120)
);

不幸的是,这种方式有点不舒服并且容易忘记,有没有其他方法可以每隔 x 秒(或其他TimeUnit)重复一次任务而不将其转换为毫秒并缩短?

4

1 回答 1

5

这在 Akka 的 2.1 版中已修复。

原因很简单:HashedWheelTimer 不知道重复的任务,所以任务需要重新调度自己,但由于这发生在滴答之后,它总是会迟到并落入下一个桶。修复是包括漂移校正,请参阅此处了解详细信息。

于 2013-01-03T19:47:58.383 回答