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 是否知道这一点cf1cf2在这种情况下携带独立的线程?如果线程依赖(例如,使用一个到数据库的连接)会发生什么变化?

更一般的,如何CompletableFuture同步线程?

4

3 回答 3

1

我不认为 CompletableFuture (CF) “同步线程”。它使用您提供的执行器公共(如果您没有提供)。

当您调用supplyAsync时,CF 会将各种任务提交到该池,该池依次管理底层线程以执行任务。

于 2015-12-04T15:34:32.353 回答
1

ACompletableFuture与任何线程都没有关系。它只是一个使用方法异步检索到的结果的持有者,该方法对该结果进行操作。

static supplyAsyncandrunAsync方法只是辅助方法。supplyAsync各州的 javadoc

返回一个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)此类无法直接控制导致其完成的计算,因此取消被视为另一种形式的异常完成。方法 cancel 与 具有相同的效果completeExceptionally(new CancellationException())。方法isCompletedExceptionally()可用于确定是否 CompletableFuture以任何异常方式完成。

CompletableFuture对象不控制处理。

于 2015-12-06T19:41:18.697 回答
0

它不知道,也不会尝试同步任何东西。正确同步对可变共享数据的访问仍然是客户端的责任。

于 2015-12-04T15:58:51.850 回答