Reinitialize fix delay in ScheduledExecutorService
Solution 1
You need to keep the reference of the returned ScheduledFuture<?>
object:
ScheduledFuture<?> handle =
scheduler.scheduleWithFixedDelay(runnable, 0, 5, TimeUnit.SECONDS);
With this reference you cancel the current task and create another one with the new delay:
handle.cancel(false);
handle = scheduler.scheduleWithFixedDelay(runnable, 0, 60, TimeUnit.SECONDS);
Here is an example:
public class Test5 {
static int i = 0;
static ScheduledExecutorService executor;
static Runnable runnable;
static ScheduledFuture<?> future;
public static void main(String args[]) throws InterruptedException{
executor = Executors.newScheduledThreadPool(1);
runnable = new Runnable() {
@Override
public void run() {
System.out.println("Inside runnable" + i++);
}
};
future = executor.scheduleWithFixedDelay(runnable, 0, 5, TimeUnit.SECONDS);
Thread.sleep(20000l);
changeDelay();
}
public static void changeDelay() {
boolean res = future.cancel(false);
System.out.println("Previous task canceled: " + res);
future = executor.scheduleWithFixedDelay(runnable, 0, 20, TimeUnit.SECONDS);
}
}
Solution 2
As I see ScheduledExecutorService.scheduleWithFixedDelay(runnable, initDelay , delay, TimeUnit.SECONDS)
returns ScheduledFuture
which doesn't have a method setDelay(delay)
which will allow it to change the delay once created.
The best option would be to cancel the current runnable ScheduledFuture.cancel(false)
and start a new scheduled task with the help of scheduleWithFixedDelay
using new delay value.
DO NOT CALL changeDelay
from run
method. Instead call it from main
method itself like below
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
public class ScheduledExecutorExample {
static int i = 0;
static ScheduledExecutorService executor;
static Runnable runnable;
static ScheduledFuture<?> future;
public static void main(String args[]) {
executor = Executors.newScheduledThreadPool(1);
runnable = new Runnable() {
@Override
public void run() {
System.out.println("Inside runnable" + i++);
}
};
future = executor.scheduleWithFixedDelay(runnable, 0, 2, TimeUnit.SECONDS);
try {
Thread.sleep(4000); //sleeping for 2 seconds
} catch (InterruptedException e) {
e.printStackTrace();
}
changeDelay();
}
public static void changeDelay() {
future.cancel(false);
future = executor.scheduleWithFixedDelay(runnable, 0, 10, TimeUnit.SECONDS);
}
}
You see that after a while the delay changes to 10 seconds from 2 seconds
Souvik
Updated on July 18, 2022Comments
-
Souvik almost 2 years
As per my requirement, I have to execute some particular code after certain period of time. To do the same I have chose
ScheduledExecutorService.scheduleWithFixedDelay(runnable, 0, 5, TimeUnit.SECONDS)
and it's working fine for me. But according to my another requirement, the time mentioned infixedDelay
should be configurable at runtime. Means, currently total Delay is 5 seconds but latter if user want then can change the time into 60 seconds and in runtimefixedDelay
will run after 60 seconds. Any help would be appreciable.Please see the code:
static int i = 0; static ScheduledExecutorService executor; static Runnable runnable; static ScheduledFuture<?> future; public static void main(String args[]) { executor = Executors .newScheduledThreadPool(1); runnable = new Runnable() { @Override public void run() { System.out.println("Inside runnable" + i++); changeDelay(); } }; future = executor.scheduleWithFixedDelay(runnable, 0, 5, TimeUnit.SECONDS); } public static void changeDelay() { future.cancel(false); future = executor.scheduleWithFixedDelay(runnable, 0, 10, TimeUnit.SECONDS); }
Here I have used changeDelay method to change the delay time. But it's not working.
-
Rahul Hawge about 7 yearsHow do i change the timing back and forth depending on a condition? Currently once i changed the scheduled time, I am not able to reschedule it