Re: CompletableStage.whenComplete(): Completes the stage after calling the BiConsumer

Nathan and Ila Reynolds via Concurrency-interest <[email protected]>
Newsgroups gmane.comp.java.jsr.166-concurrency
Message-ID <[email protected]>
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
    return("Hello");
}

public void doSomething1()
{
    doSomething2();
}

public void doSomething2()
{
    doSomething3();
}

public void doSomething3()
{
    doSomething4();
}

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());
}

-Nathan

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 <[email protected] 
> <mailto:[email protected]>> 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?

_______________________________________________
Concurrency-interest mailing list
[email protected]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.