重新初始化ScheduledExecutorService中的修复延迟

时间:2013-05-02 08:11:08

标签: java java.util.concurrent

根据我的要求,我必须在一段时间后执行一些特定的代码。为了做到这一点,我选择了ScheduledExecutorService.scheduleWithFixedDelay(runnable, 0, 5, TimeUnit.SECONDS),它对我来说很好。但根据我的另一个要求,fixedDelay中提到的时间应该可以在运行时配置。均值,当前总延迟为5秒,但后者如果用户需要则可以将时间更改为60秒,运行时fixedDelay将在60秒后运行。任何帮助都会很明显。

请参阅代码:

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);
    }

这里我使用了changeDelay方法来改变延迟时间。但它不起作用。

2 个答案:

答案 0 :(得分:10)

您需要保留返回的ScheduledFuture<?>对象的引用:

ScheduledFuture<?> handle =
       scheduler.scheduleWithFixedDelay(runnable, 0, 5, TimeUnit.SECONDS);

使用此引用,您将取消当前任务并使用新延迟创建另一个任务:

handle.cancel(false);    
handle = scheduler.scheduleWithFixedDelay(runnable, 0, 60, TimeUnit.SECONDS);

以下是一个例子:

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);
    }
}

答案 1 :(得分:3)

我看到ScheduledExecutorService.scheduleWithFixedDelay(runnable, initDelay , delay, TimeUnit.SECONDS)返回ScheduledFuture 的方法setDelay(delay),这将允许更改延迟一旦创建。

最佳选择是取消当前可运行的ScheduledFuture.cancel(false),并在scheduleWithFixedDelay的帮助下使用新的延迟值启动新的计划任务。

来自changeDelay方法的

请勿致电 run。而是从main方法本身调用它,如下面的

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);
    }
}

你看到一段时间后延迟从2秒变为10秒