ImranRazaKhan
ImranRazaKhan

Reputation: 2297

How to schedule task for start of every hour

I'm developing a service that suppose to start of every hour repeating exactly on the hour (1:00PM, 2:00PM, 3:00PM, etc.).

I tried following but it has one problem that for first time i have to run the program exactly at start of hour and then this scheduler will repeat it.

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

Any suggestion to repeat my task regardless when i run the program?

Regards, Imran

Upvotes: 15

Views: 19567

Answers (5)

atilauy
atilauy

Reputation: 41

If you are developing an Java EE application, not necessarily using Spring (as indicated in @deepmoteria's answer), you can also use the @Schedule annotation.

See Scheduling in Jakarta EE.

Upvotes: 0

K Erlandsson
K Erlandsson

Reputation: 13696

The millisToNextHour method in krishnakumarp's answer can be made more compact and straightforward in Java 8, which would result in the following code:

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);
}

Upvotes: 10

krishnakumarp
krishnakumarp

Reputation: 9295

I would also suggest Quartz for this. But the above code can be made to run first at the start of the hour using the initialDelay parameter.

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;
}

Upvotes: 17

deepmoteria
deepmoteria

Reputation: 2441

If you are using the spring in your service than you can directly use the annotation based scheduler @Schedule annotation which takes cron expression as a parameter or the delay in milliseconds, just add this annotation above the method you want to execute and this method will be executed. Enjoy...........

Upvotes: 2

Anonymous
Anonymous

Reputation: 18631

If you can afford to use an external library, then Quartz provides very flexible and easy to use scheduling modes. For example cron mode should be perfect for your case. Below a simple example of scheduling a certain Job to be executed every hour:

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

Have a look at the tutorial and examples to find which formulations suits your tastes. They also show how to deal with errors.

Upvotes: 7

Related Questions