を使用してタスクをスケジュールするコードがありますjava.util.Timer。私は周りを見回してExecutorServiceいて、同じことができるのを見ました。ここでの質問ですが、タスクをスケジュールするためTimerに とを使用したことがありますか?ExecutorService
Timerまた、誰かがクラスを使用して、解決した問題に遭遇したかどうかを確認したいと考えていExecutorServiceました。
を使用してタスクをスケジュールするコードがありますjava.util.Timer。私は周りを見回してExecutorServiceいて、同じことができるのを見ました。ここでの質問ですが、タスクをスケジュールするためTimerに とを使用したことがありますか?ExecutorService
Timerまた、誰かがクラスを使用して、解決した問題に遭遇したかどうかを確認したいと考えていExecutorServiceました。
Java Concurrency in Practiceによると:
Timerシステムクロックの変更に敏感になる可能性がScheduledThreadPoolExecutorあります。Timerには実行スレッドが 1 つしかないため、実行時間の長いタスクが他のタスクを遅らせる可能性があります。ScheduledThreadPoolExecutor任意の数のスレッドで構成できます。さらに、必要に応じて ( を提供することによりThreadFactory)、作成されたスレッドを完全に制御できます。TimerTaskその 1 つのスレッドを殺すためにスローされた実行時例外により、Timerデッド :-( ... つまり、スケジュールされたタスクはもう実行されません。ScheduledThreadExecutor実行時例外をキャッチするだけでなく、必要に応じてそれらを処理できます (afterExecuteからメソッドをオーバーライドすることによりThreadPoolExecutor)。スローされた例外はキャンセルされますが、他のタスクは引き続き実行されます。ScheduledThreadExecutorの代わりに使用できる場合は、使用Timerしてください。
もう1つ... ScheduledThreadExecutorJava 1.4ライブラリでは利用できませんが、クラスを持つJava 1.2、1.3、1.4へのJSR 166( java.util.concurrent)のバックポートがあります。ScheduledThreadExecutor
利用できる場合は、Java5エグゼキュータフレームワークを使用しない理由を考えるのは困難です。呼び出し:
ScheduledExecutorService ex = Executors.newSingleThreadScheduledExecutor();
ScheduledExecutorServiceと同様の機能を提供しますTimer(つまり、シングルスレッドになります)が、アクセスは少しスケーラブルになる可能性があります(内部では、クラスのように完全な同期ではなく、同時構造を使用しますTimer)。を使用すると、次のScheduledExecutorServiceような利点もあります。
newScheduledThreadPoolExecutor()またはScheduledThreadPoolExecutorクラスを参照)私が考えることができる唯一の理由についてTimerは次のとおりです。
ExecutorService はより新しく、より一般的です。タイマーは、スケジュールしたものを定期的に実行する単なるスレッドです。
ExecutorService はスレッド プールである場合もあれば、クラスタ内の他のシステムに分散して 1 回限りのバッチ実行などを行う場合もあります。
それぞれが決定するために提供するものを見てください。
タイマーの使用に関するその他の推奨事項を次に示します。
http://tech.puredanger.com/2008/09/22/timer-rules/
一般的に、私はTimerを素早く汚いものに使用し、Executorをより堅牢に使用します。
ScheduledThreadPoolExecutorの Oracle ドキュメント ページから
指定された遅延後にコマンドを実行するか、定期的に実行するようにコマンドを追加でスケジュールできるThreadPoolExecutor 。このクラスは、複数のワーカー スレッドが必要な場合、または ThreadPoolExecutor (このクラスが拡張する) の追加の柔軟性または機能が必要な場合に、Timerよりも適しています。
ExecutorService/ThreadPoolExecutorまたは、ScheduledThreadPoolExecutor複数のワーカー スレッドがある場合の明らかな選択です。
ExecutorService以上の長所Timer
Timer特にForkJoinPoolのようなExecutorServiceフレーバーを使用する複数のタスクとは異なり、利用可能な CPU コアを利用することはできません ExecutorServiceExecutorService複数のタスク間の調整が必要な場合は、共同 API を提供します。N 個のワーカー タスクを送信し、それらすべての完了を待つ必要があるとします。これは、 invokeAll APIを使用して簡単に実現できます。複数のタスクで同じことを達成したい場合Timer、それは簡単ではありません。ThreadPoolExecutorは、スレッドのライフサイクルを管理するためのより優れた API を提供します。
スレッド プールは、2 つの異なる問題に対処します。通常、タスクごとの呼び出しオーバーヘッドが削減されるため、多数の非同期タスクを実行する際のパフォーマンスが向上します。タスク。各 ThreadPoolExecutor は、完了したタスクの数など、いくつかの基本的な統計も維持します
いくつかの利点:
を。スレッドのライフサイクルを作成/管理/制御し、スレッド作成コストのオーバーヘッドを最適化できます
b. タスク(Work Stealing、ForkJoinPool、invokeAll)などの処理を制御できます。
c. スレッドの進行状況と状態を監視できます
d. より優れた例外処理メカニズムを提供します
Executors.newSingleThreadScheduledExecutor() よりも Timer を好むことがある理由は、タイマーをデーモン スレッドで実行する必要がある場合に、よりクリーンなコードを取得できるからです。
比較
private final ThreadFactory threadFactory = new ThreadFactory() {
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setDaemon(true);
return t;
}
};
private final ScheduledExecutorService timer = Executors.newSingleThreadScheduledExecutor(threadFactory);
と
private final Timer timer = new Timer(true);
これは、executorservice の堅牢性が必要ない場合に行います。