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]> |
Hmm... I just now recognize that there is a happens before edge for
whenComplete()'s action returns and when "future" completes. How does
having that happens-before edge help write code? I suppose it allows me
to carry out actions that must be visible before "future" completes and
actions that must execute after "future" completes. Are there other
abstract or concrete reasons?
> Otherwise the simplified example doesn't make it clear why you do not
assign async to future.
I could store "async" in a separate field but that wastes heap space
when I figure I only need 1 field.
I could change startSomething() to the following. I assume that
"unused" could be GCed and whenComplete() will never execute. Is this
assumption correct?
public void startSomething()
{
CompletableFuture<String> unused;
future = CompletableFuture.supplyAsync(() -> produce());
unused = future.whenComplete((value, throwable) -> doSomething1());
}
-Nathan
On 11/7/2019 5:30 PM, Alex Otenko wrote:
> UnableToInferImplicitsException
>
> You need to start with happens before edges. Some of them are program
> order.
>
> What do you want to happen before future can be seen completed, and
> what do you want to happen after it? Sounds tautological, but that's
> where you need to split the execution into two stages.
>
> Otherwise the simplified example doesn't make it clear why you do not
> assign async to future.
>
> Alex
>
> On Thu, 7 Nov 2019, 23:44 Nathan and Ila Reynolds via
> Concurrency-interest, <[email protected]
> <mailto:[email protected]>> wrote:
>
> 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]
> <mailto:[email protected]>
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>
_______________________________________________
Concurrency-interest mailing list
[email protected]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest