[concurrency-interest] CompletableStage.whenComplete(): Completes the stage after calling the BiConsumer

Nathan and Ila Reynolds nathanila at gmail.com
Thu Nov 7 18:42:09 EST 2019

UnableToParseQuestionException  ;)

Let's use the following simplified code.

CompletableFuture<String> future;

public void startSomething()
    CompletableFuture<String> async;

    async  = CompletableFuture.supplyAsync(() -> produce());
    future = async.whenComplete((value, throwable) -> doSomething1());

public String produce()
    Thread.sleep(1000);  // A long operation

public void doSomething1()

public void doSomething2()

public void doSomething3()

public void doSomething4()
    if (future.getNow(null) == null)
       throw new IllegalStateException("I wanted \"Hello\"");

Here are my questions now more refined...

Why does "future" not complete until after the action in whenComplete() 
returns?  How do I exploit this behavior?

How do I get the value from "future" in doSomething4()?

I could pass the "Hello" value through the doSomething#(), but that will 
require creating duplicate methods because other code uses the 
doSomething#() as they are.  I could pass null or value depending on the 
use case but that makes the methods complicated.

I cannot access "async" since that is long gone from the stack of 
probably another thread.  I could save "async" in a separate field but 
that wastes heap space.

I could change startSomething() to the following.  If I understand 
correctly, "unused" could be GCed and whenComplete() will never execute.

public void startSomething()
    CompletableFuture<String> unused;

    future = CompletableFuture.supplyAsync(() -> produce());
    unused = future.whenComplete((value, throwable) -> doSomething1());


On 11/7/2019 2:41 PM, Martin Buchholz wrote:
> https://docs.oracle.com/en/java/javase/13/docs/api/java.base/java/util/concurrent/CompletionStage.html#whenComplete(java.util.function.BiConsumer)
> On Thu, Nov 7, 2019 at 10:49 AM Nathan and Ila Reynolds via 
> Concurrency-interest <concurrency-interest at cs.oswego.edu 
> <mailto:concurrency-interest at cs.oswego.edu>> wrote:
>     For CompletableStage.whenComplete(), the Javadoc says "The returned
>     stage is completed when the action returns."  What is the
>     reasoning for
>     completing the future after action returns? 
> The result of the returned stage depends on whether the action failed 
> or not.
>     How do I run action after
>     the future completes?
> Why can't you just attach a completion action to either the stage 
> returned by whenComplete or its source?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20191107/1fddf080/attachment.html>

More information about the Concurrency-interest mailing list