Java8で追加されたjava.util.concurrent.CompletableFuture
クラスとキャンセル動作について。
CompletableFuture#cancel
メソッドは、実行中の非同期処理に割り込み(interrupt)キャンセルしない。- 該当
CompletableFuture
が未完了の場合、CancellationException
例外送出で例外完了となる。(完了済みの処理ステージには作用しない) CompletableFuture
に継続処理が存在する場合、キャンセル動作は後続の処理ステージ*1にのみ作用する。
メソッドチェイン形式で記述している場合、処理チェイン全体が自動的にキャンセルされる訳では無いことに注意。
// 非同期処理チェイン CompletableFuture<V> future = CompletableFuture. .supplyAsync(() -> generateT()) // T generateT(); .thenApplyAsync(t -> processT(t)); // U processT(T); .thenApplyAsync(u -> processU(u)); // V processU(U); //... future.cancel(true);
上記コードにおいて、future
は最終段thenApplyAsync
メソッドが返したCompletableFuture
オブジェクトのため、cancelメソッドにより同処理ステージのみが例外完了した状態となる。このとき、未完了であってもgenerateT
, processT
, processU
メソッドの非同期処理はそのまま継続実行され、最終的な処理結果オブジェクト(V
型)は単に破棄される。
CompletableFutureには、次のポリシーを持つFutureも実装されています。
http://docs.oracle.com/javase/jp/8/docs/api/java/util/concurrent/CompletableFuture.html
- (
FutureTask
とは異なり)このクラスは自身を完了させる計算を直接制御できないため、取消しは単に別形式の例外完了として処理されます。cancel
メソッドの効果はcompleteExceptionally(new CancellationException())
と同じです。isCompletedExceptionally()
メソッドは、CompletableFutureが例外で完了したかどうかを判定するために使用できます。
public boolean cancel(boolean mayInterruptIfRunning)
まだ完了していない場合は、このCompletableFutureを
CancellationException
で完了します。このCancellationException
によってCancellationException
が発生するため、まだ完了していない依存するCompletableFutureも例外で完了します。パラメータ:
http://docs.oracle.com/javase/jp/8/docs/api/java/util/concurrent/CompletableFuture.html#cancel-boolean-
mayInterruptIfRunning
- 処理の制御に割込みは使用されないため、この実装ではこの値に効果はありません。
関連URL
*1:CompletableFuture クラスは CompletionStage インタフェースを実装する