2

次のダミー コードがあるとします。

CompletableFuture<BigInteger> cf1 = CompletableFuture.supplyAsync(() -> BigInteger.valueOf(2L));
CompletableFuture<BigInteger> cf2 = CompletableFuture.supplyAsync(() -> BigInteger.valueOf(3L));
cf1.thenCombine(cf2, (x, y) -> x.add(y)).thenAccept(System.out::println);

この場合、 JVM はそれを認識し、独立したスレッドを実行しますかcf1? cf2また、スレッドが依存する場合 (たとえば、データベースへの接続を 1 つ使用する場合) はどうなりますか?

より一般的には、どのようにCompletableFutureスレッドを同期しますか?

4

3 に答える 3

1

ACompletableFutureはどのスレッドとも関係ありません。これは、その結果を操作するメソッドを使用して非同期的に取得された結果の単なるホルダーです。

およびメソッドは単なるヘルパー メソッドですstatic supplyAsync。状態runAsyncの javadocsupplyAsync

指定された を呼び出すことによって取得された値を使用して、 でCompletableFuture実行されているタスクによって非同期的に完了されるnew を返します。ForkJoinPool.commonPool()Supplier

これはほぼ同等です

Supplier<R> sup = ...;
CompletableFuture<R> future = new CompletableFuture<R>();
ForkJoinPool.commonPool().submit(() -> {
     try {
        R result = sup.get();
        future.complete(result);
    } catch (Throwable e) {
        future.completeExceptionally(e);
    }
});
return future;

が返されCompletableFuture、タスクがプールに送信される前に完了することもできます。

より一般的には、どのようにCompletableFutureスレッドを同期しますか?

どのスレッドがその上で動作しているかがわからないため、そうではありません。これは、 javadocでさらに示唆されています。

( とは異なりFutureTask) このクラスは、それを completed にする計算を直接制御しないため、キャンセルは例外的な完了の別の形式として扱われます。メソッド cancel は と同じ効果がありcompleteExceptionally(new CancellationException())ます。メソッドisCompletedExceptionally()を使用して CompletableFuture、例外的な方法で完了したかどうかを判断できます。

CompletableFutureオブジェクトは処理を制御しません。

于 2015-12-06T19:41:18.697 に答える
1

CompletableFuture (CF) が「スレッドを同期する」とは思いません。提供したエグゼキュータを使用するか、提供していない場合は共通プールを使用します。

を呼び出すsupplyAsyncと、CF はさまざまなタスクをそのプールにサブミットします。プールは、タスクを実行するために基礎となるスレッドを順番に管理します。

于 2015-12-04T15:34:32.353 に答える