79

スケジュールされたタスクを実装するためにいくつかのコードを試していて、これらのコードを思いつきました。

import java.util.*;

class Task extends TimerTask {


    int count = 1;

    // run is a abstract method that defines task performed at scheduled time.
    public void run() {
        System.out.println(count+" : Mahendra Singh");
        count++;
    }
}

class TaskScheduling {

   public static void main(String[] args) {
       Timer timer = new Timer();


       // Schedule to run after every 3 second(3000 millisecond)
       timer.schedule( new Task(), 3000);   
   }
}

私の出力:

1  :  Mahendra Singh

コンパイラが 3 秒間隔で一連の Mahendra Singh を出力することを期待していましたが、約 15 分待ったにもかかわらず、1 つの出力しか得られませんでした...どうすればこれを解決できますか?

4

4 に答える 4

83

ScheduledExecutorService以上のメリットTimer

ScheduledThreadPoolExecutorTimerを使用する代わりに、 ScheduledExecutorServiceインターフェースの実装を提供したいと思います。「Java in Concurrency」によると、Timer クラスよりもいくつかの利点があります。

Timerは、タイマー タスクを実行するためのスレッドを 1 つだけ作成します。タイマー タスクの実行に時間がかかりすぎると、他のタスクのタイミングの精度 TimerTaskが低下する可能性があります。繰り返しTimerTaskタスクが 10 ミリ秒ごとに実行されるようにスケジュールされていて、別のタイマー タスクの実行に 40 ミリ秒かかる場合、繰り返しタスクは (固定レートでスケジュールされているか固定遅延でスケジュールされているかに応じて) 4 回連続して呼び出されます。実行中のタスクが完了するか、4 つの呼び出しが完全に「失敗」します。スケジュールされたスレッド プールは、延期された定期的なタスクを実行するための複数のスレッドを提供できるようにすることで、この制限に対処します。

TimerTask Timer のもう 1 つの問題は、 aが未チェックの例外をスローした場合に動作が低下することです。別名「糸漏れ」

タイマー スレッドは例外をキャッチしないため、からスローされた未チェックの例外TimerTaskによってタイマー スレッドが終了します。この状況では、タイマーもスレッドを復活させません。代わりに、タイマー全体がキャンセルされたと誤って想定します。この場合、既にスケジュールされているがまだ実行されていない TimerTask は実行されず、新しいタスクをスケジュールすることはできません。

DelayQueueまた、独自のスケジューリング サービスを構築する必要がある場合の別の推奨事項として、 のスケジューリング機能を提供するBlockingQueue実装であるを使用することで、ライブラリを利用できる場合がありますScheduledThreadPoolExecutorDelayQueueは、Delayed オブジェクトのコレクションを管理します。Delayed にはそれに関連付けられた遅延時間がありDelayQueue、その遅延が期限切れになった場合にのみ要素を取得できます。オブジェクトはDelayQueue、遅延に関連付けられた時間までに順序付けされて返されます。

于 2010-12-28T09:11:20.803 に答える
79

使用するtimer.scheduleAtFixedRate

public void scheduleAtFixedRate(TimerTask task,
                                long delay,
                                long period)

指定されたタスクを、指定された遅延後に開始して、固定レートで繰り返し実行するようにスケジュールします。後続の実行は、指定された期間で区切られたほぼ一定の間隔で行われます。
固定レートの実行では、各実行は、最初の実行のスケジュールされた実行時間に対して相対的にスケジュールされます。なんらかの理由 (ガベージ コレクションやその他のバックグラウンド アクティビティなど) で実行が遅延した場合、「追いつく」ために 2 つ以上の実行が立て続けに発生します。長期的には、実行頻度は指定された期間の逆数になります (Object.wait(long) の基礎となるシステム クロックが正確であると仮定します)。

固定レートの実行は、毎正時にチャイムを鳴らしたり、毎日特定の時刻にスケジュールされたメンテナンスを実行したりするなど、絶対時間に敏感な繰り返しアクティビティに適しています。また、毎秒 1 回 10 秒間作動するカウントダウン タイマーなど、一定回数の実行を実行するための合計時間が重要な繰り返しアクティビティにも適しています。最後に、固定レート実行は、相互に同期を維持する必要がある複数の繰り返しタイマー タスクをスケジュールする場合に適しています。

パラメーター:

  • task - スケジュールされるタスク。
  • delay - タスクが実行されるまでのミリ秒単位の遅延。
  • period - 連続するタスク実行間のミリ秒単位の時間。

スロー:

  • IllegalArgumentException - delay が負の場合、または delay + System.currentTimeMillis() が負の場合。
  • IllegalStateException - タスクがすでにスケジュールされているかキャンセルされている場合、タイマーがキャンセルされた場合、またはタイマー スレッドが終了した場合。
于 2010-12-28T08:01:02.703 に答える
15
public void schedule(TimerTask task,long delay)

指定された遅延の後に指定されたタスクを実行するようにスケジュールします。

あなたがしたい:

public void schedule(TimerTask task, long delay, long period)

指定されたタスクを、指定された遅延の後に開始して、固定遅延で繰り返し実行するようにスケジュールします。以降の実行は、指定された期間で区切られたほぼ一定の間隔で行われます。

于 2010-12-28T06:54:33.477 に答える
2
timer.scheduleAtFixedRate( new Task(), 1000,3000); 
于 2016-03-03T07:54:52.320 に答える