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 allOf
1 with thenRun
2. 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();
}