Java – Get a single result from CompletableFuture.allof().

Get a single result from CompletableFuture.allof()…. here is a solution to the problem.

Get a single result from CompletableFuture.allof().

I have a class that uses CompletableFutures to make concurrent requests to two related services.

My code looks like this:

@Builder
@Slf4j
public class TestClass {

@NonNull private final ExecutorService threadPool = Executors.newFixedThreadPool(2);
    @NonNull private final dependency1Client;
    @NonNull private final dependency2Client;

public void myMethod() {

RequestObject1 firstDependencyRequest = RequestObject1.builder()
                .attribute1("someValue")
                .attribute2("secondValue");

CompletableFuture<ResultStructure1> future1 = CompletableFuture.supplyAsync(() -> dependency1Client.call(firstDependencyRequest), threadPool);
        RequestObject2 secondDependencyRequest = RequestObject2.builder()
                .attribute1("someValue")
                .attribute2("secondValue");

CompletableFuture<ResultStructure2> future2 = CompletableFuture.supplyAsync(() -> dependency2Client.call(secondDependencyRequest), threadPool);

try {
            CompletableFuture finalFuture = CompletableFuture.allOf(future1, future2);

} catch (ExecutionException| InterruptedException e) {
            log.error("Exception calling dependency", e);
            throw new RuntimeException(e);
        }
    }
}

I need the result of two calls to the relevant service. How do I get them without making blocking calls? I initially thought I’d do future1.get(), but this is a blocking call and I have to wait until I get the result of the first API call.

Is there a way to get the results from these two calls?

Solution

As the JavaDoc of CompletableFuture.allOf() stands for:

Otherwise, the results, if any, of the given CompletableFutures are not reflected in the returned CompletableFuture, but may be obtained by inspecting them individually.

This effectively means that you have to call join() or get() on them. If you do this in the chain after allOf(), it won’t block because it already guarantees that all of this is done.

Note that in your particular case, if you only have 2 futures, use >thenCombine() may be simpler, which gives you easier access to 2 results.

Related Problems and Solutions