Easy to understand explanation of completable future

We have Future and Executor to execute our asynchronous tasks. Why do we need this?
When we use Future to obtain asynchronous execution results, there are two methods: call Get() or poll whether isDOne() is True
Both methods are not very good, because the main thread will also be forced to wait.

In order to reduce this wait, JAVA8 introduces this CP and improves the Future. You can pass in the callback object.

What methods does this class contain and how to use them?
There are many methods. There are about 50 Simple memories one by one, which is very troublesome. Therefore, they are divided into the following categories:

Create class
completeFuture can be used to create default return values
runAsync executes asynchronously and has no return value
supplyAsync executes asynchronously and has a return value
After anyOf is executed, the next action can be performed
allOf complete all tasks before proceeding to the next task
Code example:

// Asynchronous task, no return value, using the internal forkjoin thread pool
CompletableFuture c1 = CompletableFuture
.runAsync(()->{System.out.println("Turn on the switch and start making. Don't worry")});

// Asynchronous task, no return value, using custom thread pool
CompletableFuture c11 = CompletableFuture
.runAsync(()->{System.out.println("Turn on the switch and start making. Don't worry")},newSingleThreadExecutor());

// Asynchronous tasks, with return values, use the internal default thread pool
CompletableFuture<String> c2 = CompletableFuture
.supplyAsync(()->{System.out.println("Wash rice");return "Clean rice";});

// As long as one is completed, it will be completed. If one throws an exception, it will carry an exception
CompletableFuture.anyOf(c1,c2);

// You must wait for all future to be completed
CompletableFuture.allOf(c1,c2);

Status value class
join merge results, wait
Get merge and wait for results, which can increase the timeout; The difference between get and join is that join will only throw unchecked exceptions, and get will return specific exceptions
getNow returns the result or exception if the result calculation is completed or abnormal; Otherwise, the value of valueIfAbsent is returned
isCancelled
isCompletedExceptionally
isDone

// Do not throw exceptions, blocking wait
future.join()
// If there is an exception, an exception will be thrown, blocking waiting and infinite waiting
future.get()
// If there is an exception, an exception will be thrown. The longest waiting time is 1 hour. After one hour, if there is no data, an exception will be thrown.
future.get(1,TimeUnit.Hours)

The control class is used to actively control the completion behavior of completabilefuture
complete
completeExceptionally
cancel

3 Two methods:
// complete
future.complete("rice");
// abnormal
future.completeExceptionally();
// Cancel, the parameter has no practical meaning and is useless.
future.cancel(false);

The most important feature of the continuation class completabilefuture. Without this, completabilefuture is meaningless and is used to inject callback behavior.
There are many connection methods, which can be summarized into the following three categories:

  1. CompletableFuture + (Runnable,Consumer,Function)
CompletableFuture future = CompletableFuture.supplyAsync(()->{
    System.out.println("Put in and wash the materials for making rice");
    return "Clean rice without COVID-19.";
}).thenAcceptAsync(result->{
    System.out.println("Power on, set the mode and start cooking rice");
}).thenRunAsync(()->{
    System.out.println("The rice is ready to eat");
})
  1. CompletableFuture + CompletableFuture

  2. Completable future + processing results

thenApply, thenApplyAsync
thenAccept, thenAcceptAsync
thenRun, thenRunAsync
thenCombine, thenCombineAsync
thenAcceptBoth, thenAcceptBothAsync
runAfterBoth, runAfterBothAsync
applyToEither, applyToEitherAsync
acceptEither, acceptEitherAsync
runAfterEither, runAfterEitherAsync
thenCompose, thenComposeAsync
whenComplete, whenCompleteAsync
handle, handleAsync
exceptionally

To sum up:

There are many methods above. We don't need to memorize them by rote. It will be much more convenient to memorize the rules according to the following rules:

Methods ending with Async are asynchronous methods, while those without Async are synchronous methods. Generally, an asynchronous method corresponds to a synchronous method.
Methods ending with Async suffix have two overloaded methods, one is to use the forkjoin thread pool of content, and the other is to use the custom thread pool
For a method starting with run, its entry parameters must be parameterless and have no return value, which is similar to executing the Runnable method.
For methods starting with supply, the entry also has no parameters, but has a return value
For methods beginning or ending with Accept, the entry parameter has parameters, but there is no return value
For methods beginning or ending with Apply, the entry has parameters and return values
The method with either suffix indicates that whoever completes it first will consume it

By remembering the above, you can basically remember most of the methods, and the rest can be remembered separately.

Completable future is easy to understand

Tags: Java Back-end future

Posted on Sat, 04 Dec 2021 18:56:48 -0500 by coolphpdude