thenCombine joins two independent results, and join waits without a checked exception - the readable way to run calls in parallel and merge them.
CompletableFuture<Integer> price = CompletableFuture.supplyAsync(() -> {
try { Thread.sleep(20); } catch (InterruptedException e) { Thread.currentThread().interrupt(); }
return 100;
});
CompletableFuture<Integer> tax = CompletableFuture.supplyAsync(() -> 18);
CompletableFuture<String> total = price.thenCombine(tax, (p, t) -> "total = " + (p + t));
System.out.println(total.join());
var chained = CompletableFuture.supplyAsync(() -> "jch")
.thenApply(String::toUpperCase)
.thenApply(s -> s + " ready");
System.out.println(chained.join());
total = 118
JCH ready
Run this yourself in the Online Java Compiler, spin up a live REST API in the API Sandbox, or practise with Java interview questions.
Published 2026-07-30