Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CompletableFuture, thenCompose method

I have some misunderstanding about the contract of thenCompose(Function<? super T,? extends CompletionStage<U>> fn). Here is what's said there:

Returns a new CompletionStage that, when this stage completes normally, is executed with this stage as the argument to the supplied function.

It seems the function accepts the result of this CompletionStage, not the CompletionStage itself. So what do they mean by that?

And what about the task represented by the returned CompletableFuture?

Runnable r;
ExecutorService es;
Function<Void, CompletableFuture<Void>>f;
//...
CompletableFuture.runAsync(r, es)
.thenCompose(f);

Does it mean, a task, represent by CompletableFuture returned by thenCompose will be executed in the same ThreadPool as the Runnable r?

like image 978
St.Antario Avatar asked Oct 18 '22 23:10

St.Antario


1 Answers

This appears to be a mistake in the JavaDoc. Other methods such as thenApply use the following formulation:

Returns a new CompletionStage that, when this stage completes normally, is executed with this stage's result as the argument to the supplied function. […]

(emphasis is my own)

Also, in Java 9, the formulation is now:

Returns a new CompletionStage that is completed with the same value as the CompletionStage returned by the given function.

When this stage completes normally, the given function is invoked with this stage's result as the argument, returning another CompletionStage. When that stage completes normally, the CompletionStage returned by this method is completed with the same value. […]

As to which thread/thread pool will execute the function, this will actually depend on the implementation.

For CompletableFuture, this is indicated at the top of the documentation:

Actions supplied for dependent completions of non-async methods may be performed by the thread that completes the current CompletableFuture, or by any other caller of a completion method.

In practice, there seem to be 2 possible cases:

  1. If this stage is already completed, then the function is applied immediately on the thread calling thenCompose();
  2. If this stage is not completed yet, the function will be applied on the thread that completes this stage (correct me if wrong).

Note that there is no "task" inside a CompletableFuture. The only "task" that the returned CompletableFuture does is binding the result of the one returned by the passed function with itself. You are in charge of executing the task that will complete the CompletableFuture your function returns.

like image 66
Didier L Avatar answered Oct 30 '22 12:10

Didier L