Search code examples
javaconcurrencyjava-8java.util.concurrentcompletable-future

How does CompletableFuture know that tasks are independent?


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?


Solution

  • 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 the ForkJoinPool.commonPool() with the value obtained by calling the given Supplier.

    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 as completeExceptionally(new CancellationException()). Method isCompletedExceptionally() can be used to determine if a CompletableFuture completed in any exceptional fashion.

    CompletableFuture objects do not control processing.