2016-10-06 17 views
2

スケジュールされたタスクを一時停止して再開する必要があります。スケジュールされたタスクの一時停止と再開

タスクをキャンセルする()コード例はたくさんありますが、再開/再開する必要があります。

public void init(){ 
    scheduledTaskExecutor.getScheduledThreadPoolExecutor().setRemoveOnCancelPolicy(true); 
} 
public void schedule(String id, Runnable task){ 
    ScheduledFuture<?> scheduledFuture = scheduledTaskExecutor.scheduleAtFixedRate(task); 
    runningTaskRegistry.put(id, task); 
} 

public void suspend(String id){ 
    ScheduledFuture<?> scheduledFuture = runningTaskRegistry.get(serviceName); 
    if(scheduledFuture != null){ 
     scheduledFuture.cancel(false); 
     try{ 
      scheduledFuture.get(); 
     } catch (InterruptedException | ExecutionException | CancellationException e){ 
      // I do not want the currently running task finishing after this point 
     } 
    } 
} 

...その後、再起動する代わりに再度スケジュールを設定する必要があります。

本当にこれを行うには最も良い方法はありますか?

+0

通常、タスクを再スケジューリングするのが最適です。 1つのハックは、[シングルスレッド実行プログラム](http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executors.html#newSingleThreadScheduledExecutor--)を使用しています。一時停止条件が偽になるまで待機するタスクを渡します。 – VGR

+0

シングルスレッドエグゼキュータはここではオプションではありません。実行するために長時間実行される数十のプロセスがあり、そのうちのいくつかはかなり長時間実行されています。 – BTakacs

答えて

0

一時停止して再開するよりもスケジュールを変更することをお勧めします。私はこれを行う方法がわからないだけでなく、一時停止したタスクがおそらくスレッドを解放しないためです。この間、他のタスクがタスクキューで待機している場合でも、それらのエグゼキュータスレッドはブロックして何もしません。

中間結果を失わないようにするには、別のキューに入れることができます。これらのキューは、新しいタスクがスケジュールされる前に取得されます。また、そのキューに基づいて一時停止および再開を実装することもできます。

+0

私は、エグゼキュータスレッドをブロックすることは良い解決策ではないことに完全に同意します。私はちょうど実行者自身がこれを一時的なリストに削除してから再スケジューリングすることができると考えました:-) Runnableの周りにWrapper/Proxyを作成して一時停止と再開を行う方法があります。一時停止時に元の実行可能ファイルを無視することによって:-) 最小限の定型コードで最小限のオーバーヘッドしか発生しません。 – BTakacs

+0

@BTakacs私はそれがあなたの仕事がやるべきことと中間結果を再利用できるかどうかにかかっていると本当に思っています。前述したように、私は効率的な*ポーズ可能なタスクと再開可能なタスクを可能にする実装は知られていません。つまり、スレッドはブロックされているだけではありません。タスクを「パーク」するために['BlockingQueue'](https://docs.oracle.com/javase/8/docs/apc/java/util/concurrent/BlockingQueue.html)を試してみることをお勧めします再び。あなたに私に例を挙げてもらいたいかどうか知らせてください。 – beatngu13

関連する問題