286

を使用してタスクをスケジュールするコードがありますjava.util.Timer。私は周りを見回してExecutorServiceいて、同じことができるのを見ました。ここでの質問ですが、タスクをスケジュールするためTimerに とを使用したことがありますか?ExecutorService

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

4

7 に答える 7

340

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

于 2009-01-03T22:22:53.493 に答える
66

利用できる場合は、Java5エグゼキュータフレームワークを使用しない理由を考えるのは困難です。呼び出し:

ScheduledExecutorService ex = Executors.newSingleThreadScheduledExecutor();

ScheduledExecutorServiceと同様の機能を提供しますTimer(つまり、シングルスレッドになります)が、アクセスは少しスケーラブルになる可能性があります(内部では、クラスのように完全な同期ではなく、同時構造を使用しますTimer)。を使用すると、次のScheduledExecutorServiceような利点もあります。

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

私が考えることができる唯一の理由についてTimerは次のとおりです。

  • Java5より前に利用可能です
  • 同様のクラスがJ2MEで提供されており、アプリケーションの移植が容易になる可能性があります(ただし、この場合、共通の抽象化レイヤーを追加することはそれほど難しくありません)。
于 2009-01-04T01:19:12.293 に答える
29

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

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

それぞれが決定するために提供するものを見てください。

于 2009-01-03T22:06:24.523 に答える
17

タイマーの使用に関するその他の推奨事項を次に示します。

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

一般的に、私はTimerを素早く汚いものに使用し、Executorをより堅牢に使用します。

于 2009-01-04T00:34:18.983 に答える
9

ScheduledThreadPoolExecutorの Oracle ドキュメント ページから

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

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

ExecutorService以上の長所Timer

  1. Timer特にForkJoinPoolのようなExecutorServiceフレーバーを使用する複数のタスクとは異なり、利用可能な CPU コアを利用することはできません ExecutorService
  2. ExecutorService複数のタスク間の調整が必要な場合は、共同 API を提供します。N 個のワーカー タスクを送信し、それらすべての完了を待つ必要があるとします。これは、 invokeAll APIを使用して簡単に実現できます。複数のタスクで同じことを達成したい場合Timer、それは簡単ではありません。
  3. ThreadPoolExecutorは、スレッドのライフサイクルを管理するためのより優れた API を提供します。

    スレッド プールは、2 つの異なる問題に対処します。通常、タスクごとの呼び出しオーバーヘッドが削減されるため、多数の非同期タスクを実行する際のパフォーマンスが向上します。タスク。各 ThreadPoolExecutor は、完了したタスクの数など、いくつかの基本的な統計も維持します

    いくつかの利点:

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

    b. タスク(Work Stealing、ForkJoinPool、invokeAll)などの処理を制御できます。

    c. スレッドの進行状況と状態を監視できます

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

于 2016-10-29T09:33:09.130 に答える
5

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 の堅牢性が必要ない場合に行います。

于 2015-04-12T20:52:27.367 に答える