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());