2012-01-17 13 views
12

未来を中断せずに中断する方法はありますか?並行性 - 未来を中断せずに中断する

java doc API:

ブール(ブールmayInterruptIfRunning)このタスクの実行をキャンセルする

試みを
をキャンセルします。タスクが が既に完了しているか、既にキャンセルされているか、または何らかの理由で をキャンセルできなかった場合、この試行は失敗します。成功した場合、このタスクはキャンセルが呼び出されたときに開始された ではありません。このタスクは決して実行されません。 タスクが既に開始されている場合、mayInterruptIfRunningパラメータ は、このタスクを実行するスレッドが、タスクを停止するために中断された であるべきかどうかを判断します。

割り込みをキャプチャするには、割り込み例外を適切にキャッチするか、Runnable/Callableメソッド内のisInterrupted()メソッドをチェックする必要があります。

しかし、すべてのスレッドがエグゼキュータ・サービスのプールであるため、今後のインターフェース

を使用して、実行中の未来を中断する方法はありませんが、誰もthread.interruptを行うことができます()。 これは、未来がキャンセルされたとき、またはスレッドプールが終了しているときにだけ割り込みが発生すると想定されているのはなぜですか?

私はFutureインタフェースに割り込み方法がない理由を理解しようとしています。 助けを歓迎します

+1

私はこの点が何であるかと思っています....それは興味深い、奇妙ではないにしても、質問です。 –

+5

問題が少ないためです。 1.)割り込みはリスクであり、タスクがいつ中断できるかはわかりません.2)未来はどんなスレッドにも結びついていません。 Interrupt Futureのスレッドは、他のFuturesを壊す可能性があります)3.キャンセルメカニズムを使用すると、レースやデッドロックに関連する最も一般的な落とし穴の1つを回避できます。4.)コードがランダムに停止されないという高い保証が得られます状態。 – Rekin

+0

"未来は非同期計算の結果を表します" - 非同期エンティティを中断することは危険です。非同期エンティティからの返信を待っていますか? –

答えて

7

理由は、未来である抽象とスレッドでの具体的な実行の違いによるものです。未来が単一のスレッドか複数のスレッドに結びついているかどうかは言えません。将来は新しいスレッドを開始したり、新しい先物を開始したりすることができます。

クライアントコードと先物の実行者の間のやりとりとして、これらの抽象化を考慮してください。概念的には、取り消すことがあなたの仕事だったので、「このタスクをキャンセルしてください」と言っても意味があります。私はそれに取り組んで忙しいかもしれません、またはまだそれを開始していない可能性があります、または完了することがありますが、それはすべて罰金です、私はあなたが私にしたい場合はそれをキャンセルします。だからこそ私たちはキャンセルメソッドを持っています。

一方、「あなたの仕事を中断する」と言っても意味がありません。アクションの結果(未来)と実行モデル(Executor)との間の分離のため、クライアントはタスクを実行するためにどのようなアクションが実行されているのかを知りません。どのようにしてクライアントは、いつ割り込みが適切で、必要であり、サポートされるかを知ることが期待できます。

+1

http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html - 割り込みはスレッドに何をしているのかを知らせ、何か他のことをしなければならないことを示すものです。スレッドが割り込みにどのように応答するかは、プログラマが決定しますが、スレッドが終了するのは非常に一般的です。 しかし、未来の場合、割り込みとは終了を意味します。 私は、割り込みによって何ができるのかにかかわらず、未来は条件を待つようにそれ自身でそれをしなければならないことに同意します。 しかし、私は未来を妨げることが意味を成していないことに同意しません。複雑さは価値がないかもしれません。 – AKSG

0

いずれにせよ、タイムアウトを使用することができますので、あなたはあなたの待機を中断します。

get(long timeout, TimeUnit unit) 
+0

あなたは実際に呼び出し元のスレッドで待っていますが、Futureから結果を得るためにはスレッドを実行するスレッドはありません。 部分的な結果を得るためにスレッドを中断することに興味深い[コーディングのチャレ​​ンジ:部分的な結果のセマンティクス](http://beust.com/weblog/2014/05/24/coding-challenge-partial-results-semantics/)があります。 –

0

これを行うのに便利な用途があります。

将来のAPIの問題は、実行が停止したことを検出するためにの機能をに提供しないためです。 isCancelled()isDone()は、Callableの実行が継続してもうれしく、trueを返します。

この段階ではFuture APIの抽象度について実際にはそうではありません。しかし、それはタスクの終了を識別することができません。別の言い方をすると、キャンセルリクエストと完了キャンセルアクションを区別することができません。

Waiting for a cancelled future to actually finishで行われたように、CountdownLatchを使用することをお勧めします。これは、待機中の発信者に、タスクが実際に完了したことを通知し、停止するように通知されただけではありません。