I want to have a concurrent multimap (a map from a key to a list of values) in Java, something like the following:
var map = new ConcurrentHashMap<String, List<String>>();
Is the following operation thread-safe, or is there a chance for a race-condition and losing one value in case of concurrent updates?
map.computeIfAbsent(key, k -> new CopyOnWriteArrayList<>()).add(value);
From what I understand, the first operation computeIfAbsent()
is atomic, so there cannot be two threads running this code and get different instances of the ArrayList, and the returned CopyOnWriteArrayList
instance is also thread safe, so add()
should be fine. Is my reasoning correct?
(let's say I cannot use any libraries, so please don't suggest Guava, etc).
Method computeIfAbsent()
is thread safe.
As javadoc says that it would be executed atomically.
The entire method invocation is performed atomically, so the function is applied at most once per key. Some attempted update operations on this map by other threads may be blocked while computation is in progress, so the computation should be short and simple, and must not attempt to update any other mappings of this map.
As a result, the map would be either updated, or the existing list would be retrieved. The whole process would be done as a single action. Therefore no data can be lost because each thread would get the same list.