• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Liutauras Vilda
  • Paul Clapham
Sheriffs:
  • paul wheaton
  • Tim Cooke
  • Henry Wong
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Piet Souris
Bartenders:
  • Mike London

Unable to understand this CompletableFuture behaviour

 
Ranch Foreman
Posts: 39
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello forum veterans,

I need a small help in understanding this CompletableFuture. I am learning this topic for my understanding.

As you can see, I first generate some random integer list. And then I try to find out max, min and near to 100 element in that list. And these three tasks should happen in parallel.



Sample Output:

In main, Start: 12:25:47.949939800
Generate: start, thread name:  ForkJoinPool.commonPool-worker-1
Generated List: [63, 55, 74, 76, 86, 35, 13, 33, 73, 29]
Generate: stop
findMax: ForkJoinPool.commonPool-worker-1 : 2022-11-26T12:25:47.973199
findMin: ForkJoinPool.commonPool-worker-2 : 2022-11-26T12:25:47.974763600
findNear100: ForkJoinPool.commonPool-worker-3 : 2022-11-26T12:25:47.975773900
Found the nearest of 100: 86
In main,   End: 12:25:47.975773900

Question: Why are other methods not printing anything ?

My observation: If I remove the delay, it simply works fine like below: But why ?

In main, Start: 12:30:01.922193700
Generate: start, thread name:  ForkJoinPool.commonPool-worker-1
Generated List: [79, 33, 63, 19, 20, 73, 35, 28, 55, 85]
Generate: stop
findMax: ForkJoinPool.commonPool-worker-1 : 2022-11-26T12:30:01.944750800
findMin: ForkJoinPool.commonPool-worker-2 : 2022-11-26T12:30:01.946752400
findNear100: ForkJoinPool.commonPool-worker-3 : 2022-11-26T12:30:01.946752400
Found the nearest of 100: 85
In main,   End: 12:30:01.947536400
Found min of list: 19
Found max of list: 85


Regards,
Ranagal
 
Sheriff
Posts: 22716
129
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Because you don't provide an Executor when calling supplyAsync, the commons fork-join pool is used for the work performed in the completable futures. That contains so-called daemon threads. Whereas non-daemon threads (like main) must end before the JVM ends, daemon threads will be "cut off" when the JVM ends (they don't prevent the JVM from exiting). In other words - the main method doesn't wait until the completable futures are actually done.

There are two ways to handle this:
1) Use an explicit ExecutorService, usually created by calling on of the static methods of Executors. While the ExecutorService hasn't been shut down by an explicit call, it will prevent the JVM from exiting.
2) Call join() or .get() on the last completable future. That will make the current (main) thread wait until the completable future is done.
 
Ranagal Adapla
Ranch Foreman
Posts: 39
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Oh Ok. Thanks for clearing my doubts.
 
Rob Spoor
Sheriff
Posts: 22716
129
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You're welcome.
 
Saloon Keeper
Posts: 14693
331
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Please note that your delay() method takes seconds, but it's implemented wrongly because Thread.sleep() takes milliseconds.
 
Ranagal Adapla
Ranch Foreman
Posts: 39
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:Please note that your delay() method takes seconds, but it's implemented wrongly because Thread.sleep() takes milliseconds.



I in fact had something like sec * 1000.

But it was one second, and then I removed 1000 and just kept sec so that I can pass just 1 when I am calling delay for my testing. Even then that method was not printing anything on the console. So, my attention went to that part and while posting the question here, I forgot to add back that 1000. This is how I missed it.

Anyway, thanks for catching it.
 
Bartender
Posts: 2266
13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi, I test your code and found out that regardless delay is there or not, the main thread won't wait for the three completablefuture calls.
Here is what I do to fix it. Each completablefuture calls the join method. They will all finish before the main thread.
Add the following code above the System.out.println("In main, End: "+ LocalTime.now());
 
Himai Minh
Bartender
Posts: 2266
13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Also, another workaround is :
 
Ranagal Adapla
Ranch Foreman
Posts: 39
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you for your time on this and also for the workaround ideas. This helped me a lot.

Regards,
Ranagal
 
reply
    Bookmark Topic Watch Topic
  • New Topic