私はScheduledExecutorServiceを使用して、そのようなタスクを提出しています:
future = scheduledExecutorService.schedule(myRunnableTask, delay, timeunit)
しかし、特定のイベントは、この作業が不要であることを信号時間の不確定量、後に発生する可能性があります。そして私は、このタスクをキャンセルする必要がある、と私は使用しています
boolean cancelled = future.cancel(false)
ライン。
キャンセルした後、私は提出され、実行可能な、実際に走ったかどうかに応じて、異なるアクションを取らなければなりません。そして、ここで何最初のOracleドキュメントへのジャンプ、リードすることができますcancelled
フラグ手段:
https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html#cancel(boolean)
戻り値:falseのタスクをキャンセルすることができなかった場合は、通常、それはすでに正常に完了しましたので、true、そうでありません
つまり、戻り値について述べているすべてです。このテキスト行を書いた人はわからだったように思えるfalse
ここでは、戻り値が、私はそれを取ることができると思います。
今、それは返す場合、に焦点を当てることができますtrue
。ここでは2つの可能性があります。
- タスクが実際にキャンセルされたと実行可能で走ったことはありません。
- 実行可能な、実行中のプロセスであるため、キャンセルはできません。(私は本当にしたくないロジックを中断するいくつかのスレッドを実行しない限り)
私は両方のケースが発生して大丈夫ですが、私は1つが実際に発生した知っているし、それに応じて行動を取るようにしたいです。実行可能なプロセスであるならば、私はそれはそれの仕事を終えたと大丈夫だ、私はそれの完了を待ってから、一つのことをやりたいです。それがキャンセル、決してすべてで実行するつもりだったなら、私は別のことをしたいです。
あなたはこれへのアプローチをお勧めしてくださいできますか?私何か不足していますか?
あなたは、次のとあなたの目標を達成することができます。
- A
Set<Runnable>
のトラック続けるRunnable
スレッドプールによる実行を開始しているのを。 - A
Map<ScheduledFuture<?>, Runnable>
マッピングしScheduledFuture<?>
、そのそれぞれにRunnable
。- タスクのスケジュールを設定したら、すぐに追加する必要があり
ScheduledFuture
、そのそれぞれRunnable
にMap
。 - この挿入がにした場合
Map
、タスク自体をスケジュールして原子的に実行され、その後、あなたはそのエッジケースを回避することができますScheduledFuture
に追加されていなかったMap
、それがキャンセルされた後であっても。
- タスクのスケジュールを設定したら、すぐに追加する必要があり
私はあなたを変更することをお勧めScheduledExecutorService
しScheduledThreadPoolExecutor
ますが、その上書きすることができますどの、beforeExecute(Thread, Runnable)
方法。それはすでにタスクを実行しますスレッドが割り当てられた後、タスクがプールで実行される前に、このメソッドはすぐに呼び出されます。
このメソッドをオーバーライドするときは、追加することができますRunnable
あなたにSet<Runnable>
。
ときに、ScheduledFuture
キャンセルされ、あなたが呼び出すことができるset.contains(map.get(future))
かどうかを伝えている、Runnable
(ことScheduledFuture
にマップ)が実行されました。
あなたのことを注意Set<Runnable>
し、Map<ScheduledFuture<?>, Runnable>
実装が可能な競合状態を避けるために、スレッドセーフにする必要があります。