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 in fixedDelay
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 runtime fixedDelay
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.
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);
}
}
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
来源:https://stackoverflow.com/questions/16333244/reinitialize-fix-delay-in-scheduledexecutorservice