5

私はScheduledExecutorService.scheduleAtFixedRate次のような毎日のタスクを実行するために使用します:

executor.scheduleAtFixedRate(task, d, 24L * 3600 * 1000, TimeUnit.MILLISECONDS);

dはミリ秒単位の初期遅延です)。

エグゼキュータはExecutors.newSingleThreadScheduledExecutor()複数のタスクによって作成され、実行されますが、それらはすべて数時間間隔でスケジュールされ、最大で数分かかります。

ScheduledExecutorServiceは精度を保証しないことを知っています。それを取得するには、リアルタイムOSとJVMが必要です。しかし、それは私の仕事の要件ではありません。

JDK1.7.0_03を使用しているWindows2003Serverでは、タスクが1日あたり約10秒遅れていることに気付きました。これは、月に約5分になります。これは、私のアプリケーションでは許容範囲です。タスクを特定の現地時間に実行したいので、とにかく再スケジュールを実装する必要があります。そのため、DSTを自分で処理する必要があります。サービスは長期間実行されます-再起動せずに半年はそれほど珍しいことではありません。

それでも、ほとんどアイドル状態のシステムでは、10秒/日の不正確さはかなり高いと思います。さらに悪い動作に備える必要があるのではないかと思います。

だから私の質問はあなたの経験についてscheduleAtFixedRateです。10秒/日は正常ですか?他の環境で精度が向上するのでしょうか、それとも低下するのでしょうか(お客様はLinuxおよびSolarisサーバーも使用しています)。それとも、10秒は、私たちの環境に何か問題があることを示していますか?

4

1 に答える 1

3

非常に長時間実行されるタスクの場合、それほど驚くことではありません。もう1つの問題は、NTPなどと同期されていないnanoTime()を使用していることです。これにより、壁掛け時計がドリフトする可能性があります。

これを回避する1つの方法は、提案どおりに繰り返しスケジュールすることです。繰り返されるタスクは実際に自分自身を再スケジュールします(これが例外をスローできない理由です。以下を参照してください)。壁時計時間を使用し、日リストの節約を考慮して、最後に自分自身を再スケジュールするワンショットタスクを持つことができます。

ところで:私はあなたが例外をキャッチするか、スローアブルがスローされることを確認します。そうしないと、タスクはおそらく静かに停止します(返されたFutureオブジェクトを見ている場合を除く)

私がやっていることは少しごまかすことです。1〜10秒ごとに起動し、実行する必要があるかどうかを確認し、実行する必要がない場合は戻るタスクがあります。何千ものタスクがなく、実装がはるかに簡単な場合、オーバーヘッドは通常は取るに足らないものです。

于 2013-01-10T10:30:01.197 に答える