CompletableFuture

★API

static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier);

static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier, Executor executor);

static CompletableFuture<Void> runAsync(Runnable runnable);

static CompletableFuture<Void> runAsync(Runnable runnable, Executor executor);

static CompletableFuture<Void> allOf(CompletableFuture<?>... cfs)

static CompletableFuture<Object> anyOf(CompletableFuture<?>... cfs)

<U> CompletableFuture<U> thenApply(Function<? super T,? extends U> fn);

<U> CompletableFuture<U> thenApplyAsync(Function<? super T,? extends U> fn);

<U> CompletableFuture<U> thenApplyAsync(Function<? super T,? extends U> fn, Executor executor);

CompletableFuture<Void> thenAccept(Consumer<? super T> action);

CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> action);

CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> action, Executor executor);

CompletableFuture<Void> thenRun(Runnable action);

CompletableFuture<Void> thenRunAsync(Runnable action);

CompletableFuture<Void> thenRunAsync(Runnable action, Executor executor);

<U,V> CompletableFuture<V> thenCombine(CompletableFuture<? extends U> other, BiFunction<? super T,? super U,? extends V> fn);

<U,V> CompletableFuture<V> thenCombineAsync(CompletableFuture<? extends U> other, BiFunction<? super T,? super U,? extends V> fn);

<U,V> CompletableFuture<V> thenCombineAsync(CompletableFuture<? extends U> other, BiFunction<? super T,? super U,? extends V> fn, Executor executor);

<U> CompletableFuture<Void> thenAcceptBoth(CompletableFuture<? extends U> other, BiConsumer<? super T, ? super U> action);

<U> CompletableFuture<Void> thenAcceptBothAsync(CompletableFuture<? extends U> other, BiConsumer<? super T, ? super U> action);

<U> CompletableFuture<Void> thenAcceptBothAsync(CompletableFuture<? extends U> other, BiConsumer<? super T, ? super U> action, Executor executor);

CompletableFuture<Void> runAfterBoth(CompletableFuture<?> other, Runnable action);

CompletableFuture<Void> runAfterBothAsync(CompletableFuture<?> other, Runnable action);

CompletableFuture<Void> runAfterBothAsync(CompletableFuture<?> other, Runnable action, Executor executor);

<U> CompletableFuture<U> applyToEither(CompletableFuture<? extends T> other, Function<? super T, U> fn);

<U> CompletableFuture<U> applyToEitherAsync(CompletableFuture<? extends T> other, Function<? super T, U> fn);

<U> CompletableFuture<U> applyToEitherAsync(CompletableFuture<? extends T> other, Function<? super T, U> fn, Executor executor);

CompletableFuture<Void> acceptEither(CompletableFuture<? extends T> other, Consumer<? super T> action);

CompletableFuture<Void> acceptEitherAsync(CompletableFuture<? extends T> other, Consumer<? super T> action);

CompletableFuture<Void> acceptEitherAsync(CompletableFuture<? extends T> other, Consumer<? super T> action, Executor executor);

CompletableFuture<Void> runAfterEither(CompletableFuture<?> other, Runnable action);

CompletableFuture<Void> runAfterEitherAsync(CompletableFuture<?> other, Runnable action);

CompletableFuture<Void> runAfterEitherAsync(CompletableFuture<?> other, Runnable action, Executor executor);

<U> CompletableFuture<U> thenCompose(Function<? super T, ? extends CompletableFuture<U>> fn);

<U> CompletableFuture<U> thenComposeAsync(Function<? super T, ? extends CompletableFuture<U>> fn);

<U> CompletableFuture<U> thenComposeAsync(Function<? super T, ? extends CompletableFuture<U>> fn, Executor executor);

CompletableFuture<T> exceptionally(Function<Throwable, ? extends T> fn);

CompletableFuture<T> whenComplete(BiConsumer<? super T, ? super Throwable> action);

CompletableFuture<T> whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action);

CompletableFuture<T> whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action, Executor executor);

<U> CompletableFuture<U> handle(BiFunction<? super T, Throwable, ? extends U> fn);

<U> CompletableFuture<U> handleAsync(BiFunction<? super T, Throwable, ? extends U> fn);

<U> CompletableFuture<U> handleAsync(BiFunction<? super T, Throwable, ? extends U> fn, Executor executor);

オブジェクト生成

(コンストラクタ) 未完了のオブジェクトを生成

runAsync Runnableを非同期実行するオブジェクトを生成

supplyAsync Supplier<U>を非同期実行するオブジェクトを生成

completedFuture U型の結果オブジェクトによる正常完了済みオブジェクトを生成

結果アクセス

complete 未完了ならば結果オブジェクトによる正常完了を設定

completeExceptionally 未完了ならば例外オブジェクトによる例外完了を設定

cancel 未完了ならばキャンセル完了を設定

obtrudeValue 強制的に結果オブジェクトによる正常完了を設定

obtrudeException 強制的に例外オブジェクトによる例外完了を設定

isDone 処理完了済みか否かを返す

isCompletedExceptionally 例外完了により完了済みか否かを返す

isCancelled キャンセル完了により完了済みか否かを返す

get 完了を待機し結果オブジェクトを返す(タイムアウト指定も可能)

join 完了を待機し結果オブジェクトを返す

getNow 完了済みなら結果オブジェクトを、未完了ならば指定値を即座に返す

処理合成

t0.thenRun(r) t0の正常完了後にRunnableを実行するオブジェクト(Void)を返す

t0.thenAccept(c) t0の正常完了後にCunsumer<T>を実行するオブジェクト(Void)を返す

t0.thenApply(f) t0の正常完了後にFunction<T,U>を実行するオブジェクト(U)を返す

t0.thenCompose(f) t0の正常完了後にFunction<T,CompletionStage<U>>を実行するオブジェクト(U)を返す

t1.runAfterBoth(u1,r) t1,u1両方が正常完了後にRunnableを実行するオブジェクト(Void)を返す

t1.thenAcceptBoth(u1,bc) t1,u1両方が正常完了後にBiCunsumer<T,U>を実行するオブジェクト(Void)を返す

t1.thenCombime(u1,bf) t1,u1両方が正常完了後にBiFunction<T,U,V>を実行するオブジェクト(V)を返す

t1.runAfterEither(u1,r) t1,u1いずれかが正常完了後にRunnableを実行するオブジェクト(Void)を返す

t1.acceptEither(t2,c) t1,t2いずれかが正常完了後にCunsumer<T>を実行するオブジェクト(Void)を返す

t1.applyToEither(t2,f) t1,t2いずれかが正常完了後にFunction<T,U>を実行するオブジェクト(U)を返す

t0.exceptionally(f) t0の例外完了後にFunction<Throwable,T>を実行するオブジェクト(T)を返す

t0.whenComplete(bc) t0の正常/例外完了後にBiCunsumer<T,Throwable>を実行するオブジェクト(Void)を返す

t0.handle(bf) t0の正常/例外完了後にBiFunction<Throwable,T,U>を実行するオブジェクト(U)を返す

allOf(t...) 全てのオブジェクト完了後に完了するオブジェクト(Void)を返す

anyOf(t...) いずれか1つのオブジェクト完了後に完了するオブジェクト(Object)を返す

★サンプル

CompletableFuture<String> future =

CompletableFuture.supplyAsync(() -> longRunningTask(params));

CompletableFuture<Double> f2 =

f1.thenApply(Integer::parseInt).thenApply(r -> r * r * Math.PI);

future.thenAcceptAsync(db -> log.debug("Result: {}", db));

CompletableFuture<String> safe =

future.exceptionally(ex -> ex.getMessage());

CompletableFuture<Integer> safe = future.handle((ok, ex) -> {

if (ok != null) {

return Integer.parseInt(ok);

}

log.warn("Problem occured", ex);

return -1;

});

CompletableFuture<CompletableFuture<Double>> f1 =

future.thenApply(this::calculate);

CompletableFuture<Double> f2 =

future.thenCompose(this::calculate);

private CompletableFuture<Double> calculate(Document doc) {...}

CompletableFuture<Customer> customerFuture = ...;

CompletableFuture<Shop> shopFuture = ...;

CompletableFuture<Route> routeFuture =

customerFuture.thenCombine(shopFuture, (cust, shop) -> findRoute(cust, shop)); //this::findRoute

customerFuture.thenAcceptBoth(shopFuture, (cust, shop) -> {

final Route route = findRoute(cust, shop);

...

});

private Route findRoute(Customer customer, Shop shop) {...}

CompletableFuture<String> fast = ...;

CompletableFuture<String> predictable = ...;

fast.acceptEither(predictable, s -> {

log.debug("Result: {}", s)

});

CompletableFuture<String> firstDone =

fast.applyToEither(predictable, Function.<String>identity());