Friday, September 30, 2022

[FIXED] How to use nested ConcurrentHashMap in Java?

Issue

I have a data structure HashMap<String, HashMap<String, String>> Now I need to add tread safety to this data structure, which one should I use?

ConcurrentHashMap<String, HashMap<String, String>>

or

ConcurrentHashMap<String, ConcurrentHashMap<String, String>>

What's the difference between these two?


Solution

ConcurrentHashMap is thread-safe. That means that every operation you perform on a ConcurrentHashMap is thread-safe as well. However, this neither guarantees that your code using ConcurrentHashMap is thread safe nor that the elements of the ConcurrentHashMap are thread safe.

If you have a ConcurrentHashMap<String, HashMap<String, String>>, it would be thread safe as long as you don't change any inner HashMaps after inserting (immutable Maps would likely be a better option in that case) or make sure that operations on the inner HashMap are synchronized in some other way. So basically, you have a thread-safe Map containing non-thread-safe values.

ConcurrentHashMap<String, HashMap<String, String>> yourMap = ...;
//assume the Map is populated with some values and accessed from multiple threads
HashMap<String, String> innerMap = yourMap.get("someKey");//thread-safe
//innerMap.put("someKey","someValue");//NOT thread-safe

However, if you have a ConcurrentHashMap<String, ConcurrentHashMap<String, String>>, operations on both the outer and inner Map will be thread safe (and String is immutable hence thread-safe as well). So as long as you don't write any non-thread-safe code around it, it will be thread safe.

Note that for best flexibility, you might want to use the interfaces instead of concrete implementations:

Map<String, Map<String, String>> yourMap = new ConcurrentHashMap<>();
//inserting like this
yourMap.put("key",new ConcurrentHashMap<>());
//do not insert non thread-safe Maps
//yourMap.put("key",new HashMap<>());//DON'T, the value will not be thread-safe

Using an interface instead of a concrete implementation allows you to change the type later easily and also allows to use with other APIs.

If you want to express concurrency in the static type, you could use ConcurrentMap instead of Map.

ConcurrentMap<String, ConcurrentMap<String, String>> yourMap = new ConcurrentHashMap<>();


Answered By - dan1st
Answer Checked By - Clifford M. (PHPFixing Volunteer)

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.