Question: 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?

Answer: 
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`](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html#supplyAsync-java.util.function.Supplier-) 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](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html)

> 
> **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.
I don't think that a CompletableFuture (CF) "synchronizes threads". It uses the executor [you have provided](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html#supplyAsync-java.util.function.Supplier-java.util.concurrent.Executor-) or the [common pool](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ForkJoinPool.html#commonPool--) if you have not provided one.

When you call `supplyAsync`, the CF submits the various tasks to that pool which in turns manages the underlying threads to execute the tasks.