Imagine that we have the following dummy code:
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);
Does JVM know that cf1
and cf2
carry independent threads in this case? And what will change if threads will be dependent (for example, use one connection to database)?
More general, how does CompletableFuture
synchronize threads?
A CompletableFuture
has no relation to any thread. It is just a holder for a result retrieved asynchronously with methods to operate on that result.
The static
supplyAsync
and runAsync
methods are just helper methods. The javadoc of supplyAsync
states
Returns a new
CompletableFuture
that is asynchronously completed by a task running in theForkJoinPool.commonPool()
with the value obtained by calling the givenSupplier
.
This is more or less equivalent to
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;
The CompletableFuture
is returned, even allowing you to complete it before the task submitted to the pool.
More general, how does
CompletableFuture
synchronize threads?
It doesn't, since it doesn't know which threads are operating on it. This is further hinted at in the javadoc
Since (unlike
FutureTask
) this class has no direct control over the computation that causes it to be completed, cancellation is treated as just another form of exceptional completion. Method cancel has the same effect ascompleteExceptionally(new CancellationException())
. MethodisCompletedExceptionally()
can be used to determine if aCompletableFuture
completed in any exceptional fashion.
CompletableFuture
objects do not control processing.