0

5分ごとにタスクを実行しようとしています。タスクは xx:00、xx:05、xx:10、xx:15 などから開始する必要があるため、時刻が xx:37 の場合、タスクは xx:40 に開始されます。

私はそれを行うために次のコードを使用しています:

    Date d1 = new Date();
    d1.setMinutes(d1.getMinutes() + 5 - d1.getMinutes()%5);
    d1.setSeconds(0);
    this.timer.schedule(new Send(), d1, TEN_MINUTES/2);

送信は次のようになります。

class Send extends TimerTask
{
    public void run()
    {
        if(SomeCondition)
                    {
                            Timestamp ts1 = new Timestamp(new java.util.Date().getTime());
                            SendToDB(ts1);
                    }
    }
}

したがって、結果は、分を % すると、結果が 0 になるという記録になるはずです。しかし、私が持っている記録時間は次のとおりです。

*05:35:00 *07:44:40 *07:54:40 *09:05:31 *09:50:00

ご覧のとおり、最初のタスクは完全に開始されましたが、その後何か問題が発生しました。

私の推測では、タスクは前のタスクが終了してから 5 分間のジャンプを計算するため、タスクの実行時間が影響しますが、それは単なる推測です。

4

3 に答える 3

2

タスクの実行にかかる時間は、スケジュールを遅らせます。のドキュメントscheduleから:

なんらかの理由 (ガベージ コレクションやその他のバックグラウンド アクティビティなど) で実行が遅れると、その後の実行も遅れます。

を使用したほうがよいでしょうscheduleAtFixedRate

または、単純なThreadwith ループを使用してタスクを繰り返し実行してみてください。ループの最後のステップは、タスクを再開するまで必要な時間スリープすることです。ループの 1 回の繰り返しに 5 分かからないと仮定すると、これにより累積的な遅延が解消されます。

public void run() {
    long start = System.currentTimeMillis();
    while (shouldRun()) {
        doTask();
        long next = start + FIVE_MINUTES;
        try {
            Thread.sleep(next - System.currentTimeMillis());
            start = next;
        } catch (InterruptedException e) {
            . . .
        }
    }
}

これにより、次の 5 分間隔で各反復が開始され、実行時間doTask()またはシステム遅延による遅延が蓄積されません。私はソースを見ていませんが、これはにあるものに近いと思いTimer.scheduleAtFixedRateます。

于 2013-01-29T08:53:16.243 に答える
1

スレッドを 5 分間スリープさせてから続行するループ内で、タスク スケジューラやスリープ コマンドを使用しないでください。

別の方法は、 Timer クラスを使用することです。

于 2013-01-29T08:51:44.880 に答える
0

私はおそらくScheduleExecutorService.scheduleAtFixedRateを利用します。これは、を使用するよりも最新のアプローチでTimerあり、多くのタスクがスケジュールされている場合に複数のワーカースレッドを持つことができます。

于 2013-01-29T09:02:48.923 に答える