• 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
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

How to use ConcurrentHashMap in a MultiThread application with Callable

 
Ranch Hand
Posts: 182
1
Oracle Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


I want to have a threading application and I use Callable interface, but I want all the threads to add simultaneously in a ConcurrentHashmap some values, and at the end of the program to print the hashmap with the results. More specifically, I have a list with some names. I iterate through the list and combine threading and in each thread if the name's length is shorter than 5 , then I want it added to the concurrent hashmap. At the end of the program I want to print the concurrent hashmap with all the names that are shorter than 5.

So my main class is the following:



and My Callable is the following


but what I get as a result is as you can see not what I wanted...


Could someone help me? What am I doing wrong?? Thanks !
 
Rancher
Posts: 5008
38
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Can you also post the print out from line 33 that shows the results?
I see it now.  line 33 is executed before the other printouts.
 
Norm Radder
Rancher
Posts: 5008
38
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Here is how I debugged the code.
Added print statement that printed map before map was returned on line 34.  Shows that the local variable: map has contents
Then looked at where map was declared: found it at two places one as local variable and one at class level.
The one at local goes away when method exits.  The one at class level is never changed.
Need to remove the declaration of the local map variable.
The return of map does not do anything.  I replaced it with return "XX"; and the code still worked.

The output shows that the print of map at line 33 in main is executed too soon, The other threads have not finished.
For a quick and dirty test added a sleep(1000) before the print in main and now see the contents of map as expected.
Instead of sleep, there are classes that will wait until all the other threads finish.  I haven't bothered to look them up yet.
 
Ranch Hand
Posts: 180
1
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You already identified the problem to be threads adding the name to the local map, instead of the concurrent hash map. Since the concurrent hash map is never updated, it will be always empty.
 
Bartender
Posts: 5478
212
  • Likes 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
And the second problem is that the map is printed too soon. So, after the executor.shutDown(), you can add:

But better would be to turn your Callable into:

then you don't need a Map as parameter to your Callable,  and in your main method you can add all your futures.get() to your map.putAll. Try it and see what you must add additionally.
 
Bartender
Posts: 2436
13
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Based on our discussion, here is what I modified.
For this class, I add a count down latch. When a thread is done with the call method, it count down by 1.
The main thread will wait until all count down = 0.


We can use the ConcurrentHashMap map instead of creating a new map inside the call method.


Here is the output:

 
Norm Radder
Rancher
Posts: 5008
38
  • Likes 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
@Himai Minh
I do not think your code properly uses the Callable interface in the AddElementsToMapCallable class.
If you comment out the implements phrase and the @Override statement and rename the call method EG callMe the code will compile and execute.
Here's my version with those edits:
 
Piet Souris
Bartender
Posts: 5478
212
  • Likes 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
@Himai
thanks, never thought of using a CountDownLatch.

Two problems that I have: the only thing that the Callable does is putting an Entry to a map. So there is no need to return anything, and therefore a Runnable seems a better choice. And, the code is not easy to follow, certainly not Norms code.

So I tried to simplify things a little, making the code a little shorter, and hopefully a tad easier to read. Let me know if you do not agree.
 
Himai Minh
Bartender
Posts: 2436
13
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi, everyone,
I modified the code by using ExecutorService's invokeAll() to invoke all the callables. Then, the ExecutorService instance will wait for 1000 millisecond for all the callables to complete and shut down.
If there are more callables, the ExecutorService may need to wait longer.


Reference https://www.baeldung.com/java-executor-service-tutorial
 
Don't get me started about those stupid light bulbs.
reply
    Bookmark Topic Watch Topic
  • New Topic