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.
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());