I have a ConcurrentHashMap
that gets filled with put
by 8 different Threads. One of the 8 Threads tries to read with a forEach
consumer. My problem is, that the ConcurrentHashMap
only has 5-7 entries.
map.put(myContent);
...
map.forEach(element -> ... do something);
If I add a map.size()
it for some reason shows all 8 entries
map.put(myContent);
map.size();
...
map.forEach(element -> ... do something);
Going through the ConcurrentHashMap
docs shows that it is not really thread-safe to iterate the map. It is not ensured to get all entries:
For aggregate operations such as putAll and clear, concurrent retrievals may reflect insertion or removal of only some entries. Similarly, Iterators, Spliterators and Enumerations return elements reflecting the state of the hash table at some point at or since the creation of the iterator/enumeration. They do not throw ConcurrentModificationException.
Is it possible to somehow wait or synchronize before I iterate to get absolutly all entries?
The documentation for ConcurrentHashMap.size()
doesn't provide any guarantees about visibility effects, it delegates to the following method which does the actual counting
final long sumCount() {
CounterCell[] as = counterCells; CounterCell a;
long sum = baseCount;
if (as != null) {
for (int i = 0; i < as.length; ++i) {
if ((a = as[i]) != null)
sum += a.value;
}
}
return sum;
}
Presumably as a side effect it makes all the elements visible in your code, but that's not something you should rely on (at least unless you understand the inner workings of ConcurrentHashMap
, I don't).
The purpose of ConcurrentHashMap
is to provide thread-safe insertion and retrieval, but I suppose getting iteration to work in a reliable way is hard or impossible. I'm not aware of any standard Maps
that would work as a replacement either, another concurrent map ConcurrentSkipListMap
also says that its iterators and spliterators are weakly consistent .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.