2016-09-11 5 views
-1

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

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秒後に開始する各1を処理したいと思います。前のスケジュールが実行されてから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は、次のタスクをスケジュールする前に完了しているかどうかを確認しようとした:

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

私はすぐ上のブロック内ScheduledFuture<?> future = taskScheduler.schedule(task, end);後、このブロックを追加する場合、 future.isDone()は常にfalseを返し、ProcessTaskrun()メソッドは呼び出されません。

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

+0

したがって、特定の時刻に開始され、他のユーザーは10秒後に開始しますか?次に、カレンダーを使用しないように代入を単に 'end'に変更しますが、前の終りの値は変更しますか? –

+0

@KoosGadellaa私は、各タスクが前のタスクが実行されてから10秒後に開始する方法を探しています。将来的には、タスクを10秒より早く完了できるように、展開する予定です。それが起こった場合、前回の終了時点から10秒後に次のスケジューリングをスケジュールしたいので、スケジューリングされた時間に頼るのではなく、実際に実行した時間に頼ります。うまくいけばそれは理にかなっている。 – user172092

+0

この点を詳しく説明する投稿を編集しました – user172092

答えて

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); 
    } 
} 
関連する問題