-1

タスクを実行するために Spring Task Scheduler を使用するのは初めてなので、これは基本的な質問かもしれません。を実装するクラス内で処理したいアイテムのリストがありますRunnable。ここに私のタスククラスがあります:

public class ProcessTask<T> implements Runnable {

private String item;

public ProcessTask(String item) {
    System.out.println("Starting process for " + item);
    this.item = item;
}

@Override
public void run() {
    System.out.println("Finishing task for " + item);
}

前のタスクが開始されてから 10 秒後に開始される項目のリストを処理したいと思います。前のタスクがスケジュールされてから 10 秒後に実行するようにそれぞれを設定できることは理解していますが、10 秒が経過する前に他のプロセスがタスクを実行する可能性があるため、それに依存したくありません。

したがって、私のメインクラスには、次のものがあります。

        Date end = new Date(cal.getTimeInMillis() + 10000); // this is the time that the task should be fired off, the first one being 10 seconds after the current time

    for(String item : items) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(end);
        System.out.println("Next task fires at " + cal.getTime());
        ProcessTask task = new ProcessTask(item);
        ScheduledFuture<?> future = taskScheduler.schedule(task, end);

        end = new Date(Calendar.getInstance().getTimeInMillis() + 10000);
    }

コードが実行されてから 10 秒後に最初のタスクが開始されます。これはすばらしいことです。ただし、残りの項目は 10 秒待たずにすぐにスケジュールされます。なぜそれが起こるのか理解しています -taskScheduler.scheduleは非同期であるため、for ループが続行され、残りの項目は 10 秒後にスケジュールされます。

ScheduledFuture次のような次のタスクをスケジュールする前に、メイン スレッドを 1 秒間スリープさせ、完了したかどうかを確認してみました。

while(!future.isDone()) {
     Thread.sleep(1000);
     System.out.println("is future done: " + future.isDone());
}

ScheduledFuture<?> future = taskScheduler.schedule(task, end);このブロックを上記のブロックの 直後に追加すると、future.isDone()常に false が返され、ProcessTask run()メソッドが呼び出されることはありません。

を使用して前のタスクが終了したかどうかを判断する方法はありますScheduledFutureか?終了していない場合は、引き続き待機しますか? これを行うための全体的なより良い方法はありますか? 前もって感謝します。

4

1 に答える 1

1

そのため、タスクがいつ終了するかはわかりませんが、10 秒後に次のタスクを実行する必要があります。したがって、計画はそのタスクが完了したときにのみ実行できます。したがって、配管を行う基本抽象クラスを用意します。

public abstract class ScheduleTaskAfterRun<T> implements Runnable {
    protected void executeContent();
    private Runnable nextTask;
    private taskScheduler; // init somehow, probably by constructor...

    public void setNextTask(Runnable r) {
        nextTask = r;
    }

    @Override
    public void run() {
        executeContent();
        scheduleNextTask();
    }

    private void scheduleNextTask() {
        if(nextTask == null) {
            System.out.println("No task to handle, finished!");
            return;
        }
        Date end = new Date(Calendar.getInstance().getTimeInMillis() + 10000);
        ScheduledFuture<?> future = taskScheduler.schedule(nextTask, end);
    }
}
于 2016-09-11T22:49:25.430 に答える