How to schedule task for start of every hour
Solution 1
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;
}
Solution 2
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);
}
Solution 3
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.
Solution 4
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...........
ImranRazaKhan
Updated on June 05, 2022Comments
-
ImranRazaKhan about 2 years
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
-
ImranRazaKhan about 12 yearswe will use scheduleWithFixedDelay or scheduleAtFixedDelay ? i think we will use scheduleAtFixedDelay. otherwise it will add execution time in repetition.
-
krishnakumarp about 12 yearsyes. in your case you should use scheduleAtFixedRate. Updated the answer
-
tonder over 5 yearsThis is helpful but note that this code will run the task 1 minute and 1 second later than the beginning of an hour.