A CompletableFuture can be explicitly completed using complete(T value), completeAsync(Supplier<? extends T> supplier), and completeAsync(Supplier<? extends T> supplier, Executor executor). T is the value returned by get(). Here it is a method that creates CompletableFuture and returns it immediately. Another thread is responsible for executing some tax computations and completing the CompletableFuture with the corresponding result:
public static CompletableFuture<Integer> taxes() {
CompletableFuture<Integer> completableFuture
= new CompletableFuture<>();
new Thread(() -> {
int result = new Random().nextInt(100);
Thread.sleep(10);
completableFuture.complete(result);
}).start();
return completableFuture;
}
And, let's call this method:
logger.info("Computing taxes ...");
CompletableFuture<Integer> cfTaxes = CustomerAsyncs.taxes();
while (!cfTaxes.isDone()) {
logger.info("Still computing ...");
}
int result = cfTaxes.get();
logger.info(() -> "Result: " + result);
A possible output will be the following:
[14:09:40] [INFO ] Computing taxes ...
[14:09:40] [INFO ] Still computing ...
[14:09:40] [INFO ] Still computing ...
...
[14:09:40] [INFO ] Still computing ...
[14:09:40] [INFO ] Result: 17
If we already know the result of CompletableFuture, then we can call completedFuture(U value) as in the following example:
CompletableFuture<String> completableFuture
= CompletableFuture.completedFuture("How are you?");
String result = completableFuture.get();
logger.info(() -> "Result: " + result); // Result: How are you?
Also, check the documentation of whenComplete() and whenCompleteAsync().