How to Schedule a Periodic Task in Java

How to schedule a periodic task in Java?

Use a ScheduledExecutorService:

 private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
scheduler.scheduleAtFixedRate(yourRunnable, 8, 8, TimeUnit.HOURS);

How to schedule a periodic background work to activate at fixed times?

I have found a simple solution, using calendar:

calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 22);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);

if (calendar.getTimeInMillis() <= System.currentTimeMillis()) {
calendar.set(Calendar.DAY_OF_MONTH, Calendar.DAY_OF_MONTH + 1);
}

and the initial delay is set like so:

.setInitialDelay(calendar.getTimeInMillis() - System.currentTimeMillis(), TimeUnit.MILLISECONDS)

and this seems to work well.

Run task periodically in Java using java.util.TimerTask

Use ExecutorService#scheduleWithFixedDelay(). This will start the 'delay' when the current task finishes (as opposed to scheduleAtFixedRate())

How do I schedule a task to run once?

While the java.util.Timer used to be a good way to schedule future tasks, it is now preferable1 to instead use the classes in the java.util.concurrent package.

There is a ScheduledExecutorService that is designed specifically to run a command after a delay (or to execute them periodically, but that's not relevant to this question).

It has a schedule(Runnable, long, TimeUnit) method that

Creates and executes a one-shot action that becomes enabled after the given delay.



Using a ScheduledExecutorService you could re-write your program like this:

import java.util.concurrent.*;

public class Scratch {
private static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
public static void main(String[] args) {
System.out.println("Starting one-minute countdown now...");
ScheduledFuture<?> countdown = scheduler.schedule(new Runnable() {
@Override
public void run() {
// do the thing
System.out.println("Out of time!");
}}, 1, TimeUnit.MINUTES);

while (!countdown.isDone()) {
try {
Thread.sleep(1000);
System.out.println("do other stuff here");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
scheduler.shutdown();
}
}

One of the nice things you get by doing things this way is the ScheduledFuture<?> object you get back from calling schedule().

This allows you to get rid of the extra boolean variable, and just check directly whether the job has run.

You can also cancel the scheduled task if you don't want to wait anymore by calling its cancel() method.



1See Java Timer vs ExecutorService? for reasons to avoid using a Timer in favor of an ExecutorService.

How do I schedule a task to run at periodic intervals?

Use timer.scheduleAtFixedRate

public void scheduleAtFixedRate(TimerTask task,
long delay,
long period)

Schedules the specified task for repeated fixed-rate execution, beginning after the specified delay. Subsequent executions take place at approximately regular intervals, separated by the specified period.

In fixed-rate execution, each execution is scheduled relative to the scheduled execution time of the initial execution. If an execution is delayed for any reason (such as garbage collection or other background activity), two or more executions will occur in rapid succession to "catch up." In the long run, the frequency of execution will be exactly the reciprocal of the specified period (assuming the system clock underlying Object.wait(long) is accurate).

Fixed-rate execution is appropriate for recurring activities that are sensitive to absolute time, such as ringing a chime every hour on the hour, or running scheduled maintenance every day at a particular time. It is also appropriate for recurring activities where the total time to perform a fixed number of executions is important, such as a countdown timer that ticks once every second for ten seconds. Finally, fixed-rate execution is appropriate for scheduling multiple repeating timer tasks that must remain synchronized with respect to one another.

Parameters:

  • task - task to be scheduled.
  • delay - delay in milliseconds before task is to be executed.
  • period - time in milliseconds between successive task executions.

Throws:

  • IllegalArgumentException - if delay is negative, or delay + System.currentTimeMillis() is negative.
  • IllegalStateException - if task was already scheduled or cancelled, timer was cancelled, or timer thread terminated.

A better way to run task periodically in Java


But how to schedule the task to start every 24 hours on 11 am every day?

This can be achieved by using the cron expression: 0 0 11 * * *.

Or is there a way to achieve this in Java code?

Yes, by using the Scheduled (Spring Framework 5.0.1.RELEASE API) annotation, for example:

@Scheduled(cron = "0 0 11 * * *", zone = "Europe/Moscow")
public void run() {
// ...
}

Additional references:

  1. Integration: 7. Task Execution and Scheduling: 7.4. Annotation Support for Scheduling and Asynchronous Execution, Spring Framework Documentation.
  2. Getting Started · Scheduling Tasks.

scheduled tasks group multithread execution in java

The Executors framework makes scheduling a repeating task quite easy.

Define your task as a Runnable or Callable.

Specify an initial delay, and how often to repeat.

ScheduledExecutorService ses = Executors. newSingleThreadScheduledExecutor() ;
ses.scheduleAtFixedRate( myRunnable , 1 , 10 , TimeUnit.SECONDS ) ;
ses.scheduleAtFixedRate( myOtherRunnable , 3 , 5 , TimeUnit.SECONDS ) ;

Be sure to shutdown the executor service. Otherwise, the backing thread pool may continue running like a zombie ‍♂️.



Related Topics



Leave a reply



Submit