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)
);

残念ながら、この方法は少し不快で忘れがちTimeUnitです。ミリ秒に変換して短縮せずに x 秒 (またはその他) ごとにタスクを繰り返す方法は他にありますか?

4

1 に答える 1

5

これは、Akkaのバージョン2.1で修正されています。

理由は非常に単純です。HashedWheelTimerは繰り返されるタスクを認識しないため、タスク自体を再スケジュールする必要がありますが、これは定義上、ティック後に発生するため、常に遅れて次のバケットに分類されます。修正にはドリフト補正が含まれていました。詳細については、こちらをご覧ください。

于 2013-01-03T19:47:58.383 に答える