精度

2013-01-10 18 views
5

は、私はこのように、日々のタスクを実行するためにScheduledExecutorService.scheduleAtFixedRateを使用しています。精度

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

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

Windows 2003サーバーでは、JDK 1.7.0_03を使用しているため、タスクは1日あたり10秒ほどスリップしていました。それは私のアプリケーションで受け入れられる月に約5分です。とにかく再スケジューリングを実装する必要があるのはおそらく、特定の現地時間にタスクを実行したいので、DSTを自分で処理する必要があります。このサービスは長期間実行されます。再起動なしで半年は珍しくありません。

まだ、ほとんどのアイドル状態のシステムでは、10秒/ 1日という不正確さはかなり高いと思うし、さらに悪い行為に備えなければならないかと思う。

私の質問はscheduleAtFixedRateでのあなたの経験についてです。 10秒/日は正常ですか?私たちの顧客はLinuxとSolarisサーバーも使用しています。あるいは、何かが私たちの環境に悪いことを示す10秒ですか?

+1

注: '24L * 3600 * 1000、TimeUnit.MILLISECONDS'は' 1、TimeUnit.DAYS'に相当します。時間単位の変換を避けることがタイムユニットの全体のポイントです! – assylias

+1

@assyliasはいですが、initialDelay dはミリ秒単位であり、TimeUnit引数は1つのみです。 – Chris

+1

QuartzまたはSpringの 'task:scheduled-tasks'を使用して特定のローカル時間にトリガーします。この問題はありません。 – luukes

答えて

2

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

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

ところで:私はあなたが例外をスローするか、Throwableをスローすることを確認します。あなたがしなければあなたの仕事は止まるでしょう。(もしあなたが未来のオブジェクトが返ってくるのを見ていない限り)

私がしているのはちょっとチートです。私は1〜10秒ごとに目を覚まし、それを実行する必要があるかどうかをチェックし、そうでない場合はチェックします。何千ものタスクがなく、実装するのがはるかに簡単な場合、オーバーヘッドは通常は自明です。