2012-04-18 24 views
10

毎時(1:00 PM、2:00 PM、3:00 PMなど)に正確に繰り返すサービスを開発しています。毎時のタスクをスケジュールする方法

私は以下のことを試みましたが、最初は時間の始まりにプログラムを正確に実行しなければならないという1つの問題があり、このスケジューラはこれを繰り返します。

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

私はプログラムを実行するときに関係なく、私の仕事を繰り返すための提案はありますか?

よろしく、 イムラン

答えて

10

私はまたこれについてQuartzを提案します。しかし、上記のコードは、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; 
} 
+1

我々はscheduleWithFixedDelayまたはscheduleAtFixedDelayを使うのでしょうか?私は、scheduleAtFixedDelayを使用すると思います。それ以外の場合は、実行時間を繰り返します。 – ImranRazaKhan

+2

はい。あなたの場合は、scheduleAtFixedRateを使用してください。回答を更新しました – krishnakumarp

7

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

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

あなたの好みに合った処方見つけるtutorialexamplesを見てください。また、エラーに対処する方法も示します。

1

サービスで春を使用している場合は、cron式をパラメータまたは遅延時間(ミリ秒単位)とするアノテーションベースのスケジューラ@Scheduleアノテーションを直接使用するよりも、実行するメソッドの上にこのアノテーションを追加してください。このメソッドが実行されます。お楽しみください...

5

次のコードにつながるkrishnakumarpのanswerのJava 8でよりコンパクトで簡単な行うことが可能でmillisToNextHour方法、:

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); 
} 
関連する問題