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
I have to create a basic task. In the Task Scheduler Library, right click on the task and select Properties No, we are starting the task only once by selecting 'One Time' on step 5, from then on, we will run this task every hour and this will go on indefinitely.
When you set up basic tasks to execute in Task Scheduler, there isn’t initially an option in the Basic Task setup for enabling the task to run on an hourly basis. This tutorial will show you how to set up tasks to run on an hourly basis, after you’ve set up a basic task to run via Task Scheduler.
For example, the task that we want to schedule hourly is called execute_python_batch_file: After we select the batch file, we go to the right tab and select ‘Properties’, and the task Properties tab should appear: An ‘Edit Trigger’ screen will appear. To set the script to run hourly, we select the ‘Repeat task…’ option and enable it.
An ‘Edit Trigger’ screen will appear. To set the script to run hourly, we select the ‘Repeat task…’ option and enable it. We select the ‘1 hour’ option, indicating that we wish for the task to execute on an hourly basis, and select the duration as indefinite under the duration option. The set options are shown in screenshot below:
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;
}
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);
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With