Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Why does concurrent put to a ConcurrentHashMap not produce the expected result?

I am trying to test concurrent puts to a ConcurrentHashMap using multiple threads, but the size of the hashmap after processing is not what I expected.

I have the following code to insert 1000 entries into a ConcurrentHashMap:

@Test
public void testThreadSafetyConcurrentHashMap() {
    Map<Integer, Integer> map = new ConcurrentHashMap<>();

    Runnable runnable = () -> {
        for (int i = 0; i < 1000; i++) {
            map.put(i, i);
        }
    };

    ExecutorService executorService = Executors.newFixedThreadPool(4);
    for (int i = 0; i < 4; i++) {
        executorService.submit(runnable);
    }

    System.out.println(map.size());
}

I am expecting 1000 items for the map.size() call but I don’t get this every time.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Can someone tell me what the problem is? I thought 4 threads putting 1000 items at the same time, would result in a total of 1000 items at the end?

>Solution :

You can use ExecutorService.invokeAll() to ensure that all threads are done with their job before the size of the map would be checked.

This method "list of Futures holding their status and results when all complete", i.e. it is blocking and that’s what we need (we are not interested in its return value and is omitted in the code below).

invokeAll() expects a collection of Callable and we can use Executors.callable() to interoporate between Runnable and Callable.

Map<Integer, Integer> map = new ConcurrentHashMap<>();
    
Runnable runnable = () -> {
    for (int i = 0; i < 1000; i++) {
        map.put(i, i);
    }
};
    
ExecutorService executorService = Executors.newFixedThreadPool(4);

executorService.invokeAll(Collections.nCopies(4, Executors.callable(runnable)));
    
System.out.println(map.size());
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading