を使用してタスクをスケジュールするコードがあります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つ... ScheduledThreadExecutor
Java 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 コアを利用することはできません ExecutorService
ExecutorService
複数のタスク間の調整が必要な場合は、共同 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 の堅牢性が必要ない場合に行います。