15

私は、毎時正確に正時に繰り返されるサービスを開発しています (午後 1:00、午後 2:00、午後 3:00 など)。

私は次のことを試みましたが、最初は正確に時間の開始時にプログラムを実行する必要があり、このスケジューラーはそれを繰り返すという1つの問題があります。

ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleWithFixedDelay(new MyTask(), 0, 1, TimeUnit.HOURS);

プログラムの実行時に関係なく、タスクを繰り返すための提案はありますか?

よろしく、イムラン

4

4 に答える 4

16

これにはクォーツもお勧めします。ただし、上記のコードは、initialDelayパラメーターを使用して、時間の開始時に最初に実行するように作成できます。

Calendar calendar = Calendar.getInstance();
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate(new MyTask(), millisToNextHour(calendar), 60*60*1000, TimeUnit.MILLISECONDS);



private static long millisToNextHour(Calendar calendar) {
    int minutes = calendar.get(Calendar.MINUTE);
    int seconds = calendar.get(Calendar.SECOND);
    int millis = calendar.get(Calendar.MILLISECOND);
    int minutesToNextHour = 60 - minutes;
    int secondsToNextHour = 60 - seconds;
    int millisToNextHour = 1000 - millis;
    return minutesToNextHour*60*1000 + secondsToNextHour*1000 + millisToNextHour;
}
于 2012-04-18T07:34:37.957 に答える
10

millisToNextHourkrishnakumarp の回答のメソッドは、Java 8 でよりコンパクトで簡単にすることができます。これにより、次のコードが生成されます。

public void schedule() {
    ScheduledExecutorService scheduledExecutor = Executors.newSingleThreadScheduledExecutor();
    scheduledExecutor.scheduleAtFixedRate(new MyTask(), millisToNextHour(), 60*60*1000, TimeUnit.MILLISECONDS);
}

private long millisToNextHour() {
    LocalDateTime nextHour = LocalDateTime.now().plusHours(1).truncatedTo(ChronoUnit.HOURS);
    return LocalDateTime.now().until(nextHour, ChronoUnit.MILLIS);
}
于 2016-03-16T09:05:29.913 に答える
7

外部ライブラリを使用する余裕がある場合、Quartzは非常に柔軟で使いやすいスケジューリング モードを提供します。たとえば、cronモードはあなたのケースに最適なはずです。以下は、特定のジョブを 1 時間ごとに実行するようにスケジュールする簡単な例です。

quartzScheduler.scheduleJob(
    myJob, newTrigger().withIdentity("myJob", "group")
                       .withSchedule(cronSchedule("0 * * * * ?")).build());

チュートリアルを見て、自分の好みに合った処方を見つけてください。また、エラーの処理方法も示します。

于 2012-04-18T06:52:52.993 に答える
1

サービスでスプリングを使用している場合は、cron 式をパラメーターとして、またはミリ秒単位の遅延を受け取るアノテーション ベースのスケジューラー @Schedule アノテーションを直接使用できます。実行するメソッドの上にこのアノテーションを追加するだけで、このメソッドは次のようになります。実行されました。楽しみ...........

于 2012-04-18T07:09:24.310 に答える