What is CompletableFuture.thenAcceptBoth() in Java?

thenAcceptBoth() is an instance method of the CompletableFuture class that combines the results of two completable futures. It takes a BiConsumer that takes the execution results of the two futures as method parameters. There is no return value.

The thenAcceptBoth method is defined in the CompletableFuture class, which is defined in the java.util.concurrent package. To import the CompletableFuture class, we use the following import statement.

import java.util.concurrent.CompletableFuture;

Syntax


public <U> CompletableFuture<Void> thenAcceptBoth(CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action)

Parameters

  • CompletionStage<? extends U> other: This is the other completable future to be completed.
  • BiConsumer<? super T, ? super U> action: This is the consumer to be executed.

Return value

This method returns a new CompletableFuture.

Code

import java.util.concurrent.*;
import java.util.function.BiConsumer;
public class Main {
static void sleep(int millis){
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
static void executionThread(){
System.out.println("Thread execution - " + Thread.currentThread().getName());
}
public static void main(String[] args){
CompletableFuture<String> completableFuture1 = CompletableFuture.supplyAsync(() -> {
sleep(1000);
String stringToPrint = "Educative";
System.out.println("----\nsupplyAsync first future - " + stringToPrint);
executionThread();
return stringToPrint;
});
CompletableFuture<String> completableFuture2 = CompletableFuture.supplyAsync(() -> {
sleep(2000);
String stringToPrint = "Edpresso";
System.out.println("----\nsupplyAsync second future - " + stringToPrint);
executionThread();
return stringToPrint;
});
BiConsumer<String, String> stringBiConsumer = (res1, res2) -> System.out.printf("---\ncompletableFuture1 result - %s\ncompletableFuture2 result - %s", res1, res2);
completableFuture1.thenAcceptBoth(completableFuture2, stringBiConsumer);
sleep(3000);
}
}

Explanation

  • Line 1: We import the relevant packages and classes.
  • Lines 5 to 11: We define a sleep() function. This makes the current thread sleep for the given amount of milliseconds.
  • Lines 13 to 15: We define a function called executionThread(). This prints the current thread of execution.
  • Lines 18 to 25: We create a completable future called completableFuture1 using the supplyAsyc() method. This method passes a supplier that sleeps for 1 second, invokes the executionThread() method, and returns a string value.
  • Lines 27 to 33: We create another completable future called completableFuture2 using the supplyAsyc() method by passing a supplier that sleeps for 2 seconds, invokes the executionThread() method, and returns a string value.
  • Line 35: We create a BiConsumer called stringBiConsumer that prints the results of both the futures to the console.
  • Line 37: thenAcceptBoth method is invoked on completableFuture1 passing completableFuture2 and stringBiConsumer as method arguments.
  • Line 38: The main thread sleeps for 3 seconds.

Free Resources