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 HashMap
s after inserting (immutable Map
s 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 - Gilberto Lyons (JavaFixing Admin)