0

私は数時間ごとにタスクを実行する必要があり、そのための最も効率的なソリューションを探しています。私は2つのアプローチについて考えました:

1)ビジーウェイト

while(true){

 doMyJob()
 wait(2*hour);

}

2)エグゼキュータスケジューリング:

executor.schedule(new MyJobTask(),2,TimeUnit.HOUR);

...

class MyJobTask implements Runnable{

void run(){

 doMyJob();
 ...
 executor.schedule(new MyJobTask(),2,TimeUnit.HOUR);

}

どのソリューションがより効率的で、どのような状況でそれぞれがより好ましいかを教えてください(もしあれば)。直感的には2つ目の解決策を選びましたが、直感を証明するものが見つかりませんでした。他に解決策がある場合は、共有してください。ソリューションはメモリ効率も高いはずです(そのため、私にはジレンマがあります。2時間ごとに単純なジョブを実行するためだけにThreadPoolオブジェクトを作成して保持する必要がありますか)。

4

2 に答える 2

3

提案されたソリューションはどれも、質問のタグに従ってターゲットにしているように見える EE コンテナー内 (スレッドをいじらないようにする必要があります) では本当にお勧めできません。

Java EE 5以降、私のテストによると、例の2時間のような長いタイムアウトで非常にうまく機能するタイマーサービスがあります。ただし、忘れてはならない点が 1 つあります。前述のチュートリアルからの引用です。

タイマーは永続的です。サーバーがシャットダウンされた場合 (またはクラッシュした場合) は、タイマーが保存され、サーバーの再起動時に再びアクティブになります。サーバーのダウン中にタイマーが切れると、コンテナーはサーバーの再起動時に @Timeout メソッドを呼び出します。

何らかの理由でこの解決策が受け入れられない場合は、Quartz Schedulerを確認する必要があります。その可能性は要件をはるかに超えていますが、少なくとも、幅広いアプリケーション サーバーとの互換性が保証されている、すぐに使用できるソリューションを提供します。

于 2012-06-20T16:43:02.267 に答える
1

どちらもほぼ同じ効率を持つはずですが、使用することをお勧めしますScheduledExecutorService

Executors.newSingleThreadScheduledExecutor()
    .scheduleAtFixedRate(new MyJobTask(), 0, 2, TimeUnit.HOUR);

ここに詳述されているいくつかの理由があります

ただし、重要なのは、ScheduledExecutorService複数のスレッドを使用できるため、時間がかかるタスクが必ずしもタスクのキューをバックアップする必要がありません (サービスは 2 つのタスクを同時に実行できます)。また、doMyJob例外がスローScheduledExecutorServiceされた場合、タスクの再スケジュールに失敗したためにキャンセルされるのではなく、タスクのスケジュールが続行されます。

于 2012-06-20T16:38:34.453 に答える