想象一下,我们有以下虚拟代码:
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
带有独立的线程?如果线程依赖(例如,使用一个数据库连接),会发生什么变化?
更一般地说,CompletableFuture
如何同步线程?
答案 0 :(得分:1)
我不认为CompletableFuture(CF)“同步线程”。如果您没有提供执行者,则使用执行者you have provided或common pool。
当您调用supplyAsync
时,CF会将各种任务提交给该池,该池又管理底层线程以执行任务。
答案 1 :(得分:1)
CompletableFuture
与任何线程无关。它只是与对该结果进行操作的方法异步检索的结果的持有者。
static
supplyAsync
和runAsync
方法只是辅助方法。 supplyAsync
状态的javadoc
返回由a异步完成的新
CompletableFuture
任务在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
不同)此类无法直接控制 导致它完成的计算,取消被视为 只是另一种特殊完成形式。方法取消有 效果与completeExceptionally(new CancellationException())
相同。 方法isCompletedExceptionally()
可用于确定是否CompletableFuture
以任何特别的方式完成。
CompletableFuture
个对象无法控制处理。
答案 2 :(得分:0)
它不知道,也没有尝试同步任何东西。正确地同步对可变共享数据的访问仍然是客户的责任。