Java ScheduledExecutorService examples
In Java, we can use ScheduledExecutorService
to run a task periodically or once time after a predefined delay by TimeUnit
.
1. Run a Task Once
The ScheduledExecutorService
accepts both Runnable
and Callable
tasks.
1.1 Run a Runnable
task after 5 seconds initial delay.
ScheduledExecutorExample.java
package com.mkyong.concurrency.executor.scheduler;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class ScheduledExecutorRunnable {
public static void main(String[] args) {
ScheduledExecutorService ses = Executors.newScheduledThreadPool(1);
Runnable task2 = () -> System.out.println("Running task2...");
task1();
//run this task after 5 seconds, nonblock for task3
ses.schedule(task2, 5, TimeUnit.SECONDS);
task3();
ses.shutdown();
}
public static void task1() {
System.out.println("Running task1...");
}
public static void task3() {
System.out.println("Running task3...");
}
}
Output
Running task1...
Running task3...
Running task2... //display after 5 seconds
1.2 Run a Callable
task after 5 seconds initial delay.
ScheduledExecutorExample.java
package com.mkyong.concurrency.executor.scheduler;
import java.util.concurrent.*;
public class ScheduledExecutorCallable {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ScheduledExecutorService ses = Executors.newScheduledThreadPool(1);
Callable<Integer> task2 = () -> 10;
task1();
//run this task after 5 seconds, nonblock for task3, returns a future
ScheduledFuture<Integer> schedule = ses.schedule(task2, 5, TimeUnit.SECONDS);
task3();
// block and get the result
System.out.println(schedule.get());
System.out.println("shutdown!");
ses.shutdown();
}
public static void task1() {
System.out.println("Running task1...");
}
public static void task3() {
System.out.println("Running task3...");
}
}
Output
Running task1...
Running task3...
10 //display after 5 seconds
shutdown!
2. Run a Task Periodically
To run a task periodically, uses scheduleAtFixedRate
2.1 Run a Runnable
task every 1 second, after 5 seconds initial delay.
ScheduledExecutorExample.java
package com.mkyong.concurrency.executor.scheduler;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
public class ScheduledExecutorRepeat {
private static int count = 0;
public static void main(String[] args) throws InterruptedException {
ScheduledExecutorService ses = Executors.newScheduledThreadPool(1);
Runnable task1 = () -> {
count++;
System.out.println("Running...task1 - count : " + count);
};
// init Delay = 5, repeat the task every 1 second
ScheduledFuture<?> scheduledFuture = ses.scheduleAtFixedRate(task1, 5, 1, TimeUnit.SECONDS);
while (true) {
System.out.println("count :" + count);
Thread.sleep(1000);
if (count == 5) {
System.out.println("Count is 5, cancel the scheduledFuture!");
scheduledFuture.cancel(true);
ses.shutdown();
break;
}
}
}
}
Output
count :0
count :0
count :0
count :0
count :0
Running...task1 - count : 1
count :1
Running...task1 - count : 2
count :2
Running...task1 - count : 3
count :3
Running...task1 - count : 4
count :4
Running...task1 - count : 5
Count is 5, cancel the scheduledFuture!
Download Source Code
$ git clone https://github.com/mkyong/java-concurrency.git
Hey love the Simplicity , what if we are looking for something that would run a thread at a specific time of the day ? are we able to set a time that the thread will be run ?
Hi,
You can set in your settings startTime and endTime when your method should work. Than inside executed method you can check if current time is between those two values. I don’t know another solution but that one works fine.
All schedule methods accept relative delays and periods as arguments, not absolute times or dates. It is a simple matter to transform an absolute time represented as a Date to the required form. For example, to schedule at a certain future date, you can use: schedule(task, date.getTime() – System.currentTimeMillis(), TimeUnit.MILLISECONDS).
I had the same question. I think a little ‘hack’ or work-around for this would be setting the task to run every 86400 seconds (86400 seconds = a day). I may be wrong, though.
Whoops. I misread your question – I am sorry
Is this code multi VM scenario is not considered. It might be possible that on multiple VMs same code executed parallely. Can you update the code for this too.
What if at scheduled time there is no free threads in pool. Shall SheduledExecutorService start task when any thread will be available later or just skip that task? Is there any policy setup for such behavior?
How can in call shutdown, if the Runnable is implemented in separate class?
I want to call shutdown in run method on some condition.
What is the use of “while (true)”