CompletableFuture: Which thread runs the thenApply-Function?

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

CompletableFuture: Which thread runs the thenApply-Function?

Jörg Hettel
Hi everyone,

the behaviour of a sequence build of CompletableFuture with non-async
methods depends on the “duration” of the tasks.

The documentation says:
“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.“

If I run the test program below on my machine, I get different outputs,
if the first task has different runtimes.

This raises the following question for me:

1. It would therefore be a good idea always to use the then<XXXX>Async
method, right?
2. What was the intent to include in each case async and non-async
versions of the methods in the API?
3. In which cases can I safely use non-async methods to build
asynchronous sequences?

Regards

Joerg

===========================================================================

With work(10000);

Thread[ForkJoinPool.commonPool-worker-1,5,main]
Thread[main,5,main]
Thread[main,5,main]
Thread[main,5,main]
done
----------------------------------------------------------------

With work(20000);

Thread[ForkJoinPool.commonPool-worker-1,5,main]
Thread[ForkJoinPool.commonPool-worker-1,5,main]
Thread[main,5,main]
Thread[main,5,main]
done
-----------------------------------------------------------------

With work(60000);

done
Thread[ForkJoinPool.commonPool-worker-1,5,main]
Thread[ForkJoinPool.commonPool-worker-1,5,main]
Thread[ForkJoinPool.commonPool-worker-1,5,main]
Thread[ForkJoinPool.commonPool-worker-1,5,main]
  -----------------------------------------------------------------

public class AsyncCalculation
{
   public static void main(String[] args)
   {
     CompletableFuture<Void> cf = CompletableFuture.supplyAsync( () -> {
                                work(10000); // Here change the value
                                System.out.println(
Thread.currentThread());
                                return 2; } )
                      .thenApply( r -> { System.out.println(
Thread.currentThread()); return r*r; } )
                      .thenApply( r -> { System.out.println(
Thread.currentThread()); return r+2; } )
                      .thenAccept(r -> {
System.out.println(Thread.currentThread() ); } );

     System.out.println("done");
     cf.join();
   }

   private static long work(int len)
   {
     long sum = 0;
     for(int i=0; i < len; i++ )
     {
       sum += Math.sqrt(i);
     }
     return sum;
   }
}

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: CompletableFuture: Which thread runs the thenApply-Function?

Martin Buchholz-3


On Fri, Jul 24, 2015 at 8:32 AM, Jörg Hettel <[hidden email]> wrote:


This raises the following question for me:

1. It would therefore be a good idea always to use the then<XXXX>Async method, right?
2. What was the intent to include in each case async and non-async versions of the methods in the API?
3. In which cases can I safely use non-async methods to build asynchronous sequences?

I think the same question applies to any chunk of code anywhere - do you want to run it async?  The answer is more often "no" than "yes", since async execution is not free.  Just like in real life!

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: CompletableFuture: Which thread runs the thenApply-Function?

Gregg Wonderly-3
In reply to this post by Jörg Hettel
I see behaviors which have to do with the thread scheduling quanta time.  If you use async in a chain, what do you expect the results to look like for the value returned by cf?

Gregg Wonderly

> On Jul 24, 2015, at 10:32 AM, Jörg Hettel <[hidden email]> wrote:
>
> Hi everyone,
>
> the behaviour of a sequence build of CompletableFuture with non-async methods depends on the “duration” of the tasks.
>
> The documentation says:
> “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.“
>
> If I run the test program below on my machine, I get different outputs, if the first task has different runtimes.
>
> This raises the following question for me:
>
> 1. It would therefore be a good idea always to use the then<XXXX>Async method, right?
> 2. What was the intent to include in each case async and non-async versions of the methods in the API?
> 3. In which cases can I safely use non-async methods to build asynchronous sequences?
>
> Regards
>
> Joerg
>
> ===========================================================================
>
> With work(10000);
>
> Thread[ForkJoinPool.commonPool-worker-1,5,main]
> Thread[main,5,main]
> Thread[main,5,main]
> Thread[main,5,main]
> done
> ----------------------------------------------------------------
>
> With work(20000);
>
> Thread[ForkJoinPool.commonPool-worker-1,5,main]
> Thread[ForkJoinPool.commonPool-worker-1,5,main]
> Thread[main,5,main]
> Thread[main,5,main]
> done
> -----------------------------------------------------------------
>
> With work(60000);
>
> done
> Thread[ForkJoinPool.commonPool-worker-1,5,main]
> Thread[ForkJoinPool.commonPool-worker-1,5,main]
> Thread[ForkJoinPool.commonPool-worker-1,5,main]
> Thread[ForkJoinPool.commonPool-worker-1,5,main]
> -----------------------------------------------------------------
>
> public class AsyncCalculation
> {
>  public static void main(String[] args)
>  {
>    CompletableFuture<Void> cf = CompletableFuture.supplyAsync( () -> {
>                               work(10000); // Here change the value
>                               System.out.println( Thread.currentThread());
>                               return 2; } )
>                     .thenApply( r -> { System.out.println( Thread.currentThread()); return r*r; } )
>                     .thenApply( r -> { System.out.println( Thread.currentThread()); return r+2; } )
>                     .thenAccept(r -> { System.out.println(Thread.currentThread() ); } );
>
>    System.out.println("done");
>    cf.join();
>  }
>
>  private static long work(int len)
>  {
>    long sum = 0;
>    for(int i=0; i < len; i++ )
>    {
>      sum += Math.sqrt(i);
>    }
>    return sum;
>  }
> }
>
> _______________________________________________
> Concurrency-interest mailing list
> [hidden email]
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest