10

私の要件によれば、一定期間後に特定のコードを実行する必要があります。私が選んだの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 メソッドを使用して遅延時間を変更しています。しかし、それは機能していません。

4

2 に答える 2

12

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);
    }
}
于 2013-05-02T08:19:19.450 に答える
4

私が見ているように、一度作成された遅延を変更できるメソッドを持っていないScheduledExecutorService.scheduleWithFixedDelay(runnable, initDelay , delay, TimeUnit.SECONDS)リターンがあります。ScheduledFuturesetDelay(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 秒に変わることがわかります

于 2013-05-02T08:20:34.717 に答える