質問

java.util.timer を使用してタスクをスケジュールするコードがあります。周りを見回してみると、 ExecutorService で同じことができることがわかりました。ここでこの質問、タイマーと ExecutorService を使用してタスクをスケジュールしましたか?

また、誰かが Timer クラスを使用し、 ExecutorService が解決した問題に遭遇したかどうかを確認したかった。

役に立ちましたか?

解決

Java同時実行の実践によると:

  • Timer はシステムクロックの変化に敏感な場合がありますが、 ScheduledThreadPoolExecutor はそうではありません。
  • Timer には実行スレッドが1つしかないため、長時間実行されるタスクは他のタスクを遅延させる可能性があります。 ScheduledThreadPoolExecutor は、任意の数のスレッドで構成できます。さらに、必要に応じて、作成されたスレッドを完全に制御できます( ThreadFactory を提供することにより)。
  • TimerTask でスローされた実行時例外は、その1つのスレッドを強制終了するため、 Timer がデッドになります:-( ...つまり、スケジュールされたタスクは実行されなくなります。 ScheduledThreadExecutor はランタイム例外をキャッチするだけでなく、必要に応じて処理することもできます( ThreadPoolExecutor から afterExecute メソッドをオーバーライドすることにより)。例外をスローしたタスクはキャンセルされますが、他のタスクは引き続き実行されます。

Timer の代わりに ScheduledThreadExecutor を使用できる場合は、そうします。

もう1つ... ScheduledThreadExecutor はJava 1.4ライブラリでは使用できませんが、 JSR 166のバックポート( java.util.concurrent )からJava 1.2、1.3、1.4 へ。これには ScheduledThreadExecutor クラスがあります。

>

他のヒント

利用可能な場合、Java 5 executorフレームワークを使用するしない理由を考えるのは困難です。呼び出し:

ScheduledExecutorService ex = Executors.newSingleThreadScheduledExecutor();

は、 Timer と同様の機能を備えた ScheduledExecutorService を提供します(つまり、シングルスレッドになります)が、アクセスはわずかに拡張可能です(内部では、 Timer クラスのように完全な同期ではなく、並行構造を使用します)。 ScheduledExecutorService を使用すると、次のような利点も得られます。

  • 必要に応じてカスタマイズできます( newScheduledThreadPoolExecutor()または ScheduledThreadPoolExecutor クラスを参照)
  • 「ワンオフ」実行は結果を返すことができます

Timer にこだわる唯一の理由については、次のとおりです。

  • Java 5より前のバージョンで利用可能です
  • 同様のクラスがJ2MEで提供されているため、アプリケーションの移植が容易になります(ただし、この場合、共通の抽象化レイヤーを追加するのはそれほど難しくありません)

ExecutorServiceはより新しく、より一般的です。タイマーは、スケジュールされたものを定期的に実行する単なるスレッドです。

ExecutorServiceはスレッドプールであるか、クラスター内の他のシステムに分散していて、1回限りのバッチ実行などを実行することもあります。

各オファーの決定内容を確認してください。

タイマーの使用に関するいくつかの優れたプラクティスを次に示します。

http://tech.puredanger.com/2008/09/22 / timer-rules /

一般的に、手早く汚れたものにはTimerを使用し、より堅牢な使用にはExecutorを使用します。

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); 

with

private final Timer timer = new Timer(true);

executorserviceの堅牢性が必要ないときにこれを行います。

ScheduledThreadPoolExecutor

  

ThreadPoolExecutor 。指定された遅延後に実行するコマンドを定期的にスケジュールしたり、定期的に実行したりできます。複数のワーカースレッドが必要な場合、または(このクラスが拡張する)ThreadPoolExecutorの追加の柔軟性または機能が必要な場合、このクラスは Timer よりも望ましいです。

ExecutorService / ThreadPoolExecutor または ScheduledThreadPoolExecutor は、複数のワーカースレッドがある場合は当然の選択です。

Timer

を介した ExecutorService の長所
  1. タイマーは、 ExecutorService とは異なり、特に ForkJoinPool
  2. ExecutorService は、複数のタスク間の調整が必要な場合にコラボレーションAPIを提供します。 N個のワーカータスクを送信し、すべてのタスクが完了するまで待つ必要があると仮定します。 invokeAll API。複数の Timer タスクで同じことを達成したい場合、それは簡単ではありません。
  3. ThreadPoolExecutor スレッドのライフサイクルを管理するためのより良いAPIを提供します。

      

    スレッドプールは、2つの異なる問題に対処します。通常、タスクごとの呼び出しオーバーヘッドが削減されるため、多数の非同期タスクを実行するときのパフォーマンスが向上し、実行時に消費されるスレッドなどのリソースを制限および管理する手段を提供しますタスクのコレクション。各ThreadPoolExecutorは、完了したタスクの数など、いくつかの基本的な統計も保持します

    いくつかの利点:

    a。スレッドのライフサイクルを作成/管理/制御できます&スレッド作成コストのオーバーヘッドを最適化する

    b。タスク(ワークスティーリング、ForkJoinPool、invokeAll)などの処理を制御できます。

    c。スレッドの進行状況と正常性を監視できます

    d。より優れた例外処理メカニズムを提供します

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top