Java Completable Futures

Running in parallel

import java.util.concurrent.CompletableFuture;
import java.lang.InterruptedException;
import java.util.concurrent.ExecutionException;

public static void main(String[] args) throws InterruptedException, ExecutionException {
    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());
    System.out.println(result.get());
}

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:

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.lang.InterruptedException;
import java.util.concurrent.ExecutionException;

public static void main(String[] args) throws InterruptedException, ExecutionException {
    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 -> {
                System.out.println(v);
            });

    Thread.sleep(100);
    executor.shutdown();
}