Java Completable Futures

Running in parallel

import java.util.concurrent.CompletableFuture;

CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Hello");
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "Beautiful");
CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> "World");

CompletableFuture<Void> combinedFuture = CompletableFuture.allOf(future1, future2, future3);

CompletableFuture<String> result = combinedFuture.thenApply(v -> future1.join() + future2.join() + future3.join());


Waiting for all

Lets assume we have a completable future, \(f\). This future, in turn, create \(N\) additional completable futures, \(f_1, f_2, \dots, f_N\). How can we set \(f\) to complete only when all \(f_1, f_2, \dots, f_N\) are also completed?

The answer is to use a combination of allOf1 with thenRun2. According to the documentation, allOf returns a new CompletableFuture that is completed when all of the given CompletableFutures complete. In turn, thenRun will execute the given action. Let's look at an example:

CompletableFuture<String> f = new CompletableFuture<>();

int N = 10;

CompletableFuture<String> f1 = CompletableFuture.completedFuture("f1");
CompletableFuture<String> f2 = CompletableFuture.completedFuture("f2");
CompletableFuture<String> f3 = CompletableFuture.completedFuture("f3");

ExecutorService executor = Executors.newSingleThreadExecutor();
    executor.submit(() -> {
        CompletableFuture.allOf(f1, f2, f3)
            .thenRun(() -> f.complete("f1,f2,f3 completed.\nProceed to finish f."));

f.thenAccept(v -> {

f1,f2,f3 completed.
Proceed to finish f.