キャンセルScheduledFutureが実際にキャンセルされていない場合はどのように識別するために?

ミハイルValiev:

私は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. タスクが実際にキャンセルされたと実行可能で走ったことはありません。
  2. 実行可能な、実行中のプロセスであるため、キャンセルはできません。(私は本当にしたくないロジックを中断するいくつかのスレッドを実行しない限り)

私は両方のケースが発生して大丈夫ですが、私は1つが実際に発生した知っているし、それに応じて行動を取るようにしたいです。実行可能なプロセスであるならば、私はそれはそれの仕事を終えたと大丈夫だ、私はそれの完了を待ってから、一つのことをやりたいです。それがキャンセル、決してすべてで実行するつもりだったなら、私は別のことをしたいです。

あなたはこれへのアプローチをお勧めしてくださいできますか?私何か不足していますか?

ジェイコブG.:

あなたは、次のとあなたの目標を達成することができます。

  • A Set<Runnable>のトラック続けるRunnableスレッドプールによる実行を開始しているのを。
  • A Map<ScheduledFuture<?>, Runnable>マッピングしScheduledFuture<?>、そのそれぞれにRunnable
    • タスクのスケジュールを設定したら、すぐに追加する必要がありScheduledFuture、そのそれぞれRunnableMap
    • この挿入がにした場合Map、タスク自体をスケジュールして原子的に実行され、その後、あなたはそのエッジケースを回避することができますScheduledFutureに追加されていなかったMap、それがキャンセルされた後であっても。

私はあなたを変更することをお勧めScheduledExecutorServiceScheduledThreadPoolExecutorますが、その上書きすることができますどの、beforeExecute(Thread, Runnable)方法。それはすでにタスクを実行しますスレッドが割り当てられた後、タスクがプールで実行される前に、このメソッドはすぐに呼び出されます。

このメソッドをオーバーライドするときは、追加することができますRunnableあなたにSet<Runnable>

ときに、ScheduledFutureキャンセルされ、あなたが呼び出すことができるset.contains(map.get(future))かどうかを伝えている、Runnable(ことScheduledFutureにマップ)が実行されました。


あなたのことを注意Set<Runnable>し、Map<ScheduledFuture<?>, Runnable>実装が可能な競合状態を避けるために、スレッドセーフにする必要があります。

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=180750&siteId=1