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:
- Integration: 7. Task Execution and Scheduling: 7.4. Annotation Support for Scheduling and Asynchronous Execution, Spring Framework Documentation.
- 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
Double Decimal Formatting in Java
Manifest Merger Failed:Attribute Application@Appcomponentfactory Cant Solve This
Android: How to Get the Current Day of the Week (Monday, etc...) in the User's Language
Android Load from Url to Bitmap
Swt Browser No More Handles Error
Cannot Run Program "Mvn" Error=2, No Such File or Directory
Reading Remote Hdfs File with Java
Why the Operating System Says It Can't Allocate Memory to Jvm When It Has Enough Memory
Why How to Successfully Move a File in Linux While It Is Being Written To
How to Parse Dates in Multiple Formats Using Simpledateformat
How to Use Swingworker in Java
Finish All Previous Activities
Listview Onitemclicklistener Not Responding
Using Visualvm to Connect to a Remote Jstatd Instance Through a Firewall