Reinitialize fix delay in ScheduledExecutorService

♀尐吖头ヾ 提交于 2019-12-03 12:20:18

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!