Java.util.timer
を使用してタスクをスケジュールするコードがあります。私は周りを見回して、ExecutorService
が同じことをするのを見ました。この質問は、タイマーとExecutorService
を使用してタスクをスケジュールしたことがありますか?
また、誰かがTimer
クラスを使用し、ExecutorService
が解決した問題に遭遇したかどうかを確認したかった。
使用できる場合、理由を考えるのは困難ですnot Java 5 executor frameworkを使用する。呼び出し:
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
は、ExecutorService
とは異なり、使用可能なCPUコアを活用できません。特に、 ForkJoinPool のようなフレーバーのExecutorService
を使用する複数のタスクではExecutorService
は、複数のタスク間の調整が必要な場合に共同APIを提供します。 N個のワーカータスクを送信し、すべてのタスクが完了するまで待つ必要があると仮定します。 invokeAll APIで簡単に実現できます。複数のTimer
タスクで同じことを達成したい場合、それは簡単ではありません。ThreadPoolExecutor は、スレッドのライフサイクルを管理するためのより良いAPIを提供します。
スレッドプールは、2つの異なる問題に対処します。通常、タスクごとの呼び出しオーバーヘッドが削減されるため、多数の非同期タスクを実行するときのパフォーマンスが向上し、スレッドのコレクションを実行するときに消費されるリソースを制限および管理する手段を提供しますタスク。各ThreadPoolExecutorは、完了したタスクの数など、いくつかの基本的な統計も保持します
いくつかの利点:
a。スレッドのライフサイクルを作成/管理/制御し、スレッド作成コストのオーバーヘッドを最適化できます
b。タスク(ワークスティーリング、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の堅牢性が必要ないときにこれを行います。