Reinitialize fix delay in ScheduledExecutorService

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.

Answers


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


Need Your Help

Granular Synthesis in iOS 6 using AudioFileServices

c++ iphone objective-c audio core-audio

I have a question regarding a sound synthesis app that I'm working on. I am trying to read in an audio file, create randomized 'grains' using granular synthesis techniques, place them into an output

Correct Syntax for left join

mysql sql

Can someone tell me why this sql query does not execute?

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.