我有一个ConcurrentHashMap,由8个不同的线程填充put。8条线程中的一条试图使用forEach使用者进行读取。我的问题是,ConcurrentHashMap只有5-7个条目.
map.put(myContent);
...
map.forEach(element -> ... do something);如果我添加了一个map.size(),它会显示所有的8个条目
map.put(myContent);
map.size();
...
map.forEach(element -> ... do something);遍历 docs表明,迭代映射并不是真正的线程安全。没有确保获得所有条目:
对于聚合操作(如putAll和clear ),并发检索可能只反映某些条目的插入或删除。类似地,迭代器、迭代器和枚举返回元素,这些元素反映了在迭代器/枚举创建时或自创建以来哈希表的状态。他们不抛ConcurrentModificationException。
在我迭代之前是否有可能等待或同步以获得所有条目?
发布于 2018-03-15 14:23:30
ConcurrentHashMap.size()的文档没有提供任何关于可见性效果的保证,它将委托给以下方法,该方法执行实际计数
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;
}作为一种副作用,它可能会使代码中的所有元素可见,但这不是您应该依赖的东西(至少除非您了解ConcurrentHashMap的内部工作原理,我不这么认为)。
ConcurrentHashMap的目的是提供线程安全的插入和检索,但我认为让迭代以可靠的方式工作是困难的或不可能的。我也不知道有任何标准的Maps可以代替它,另一个并发映射ConcurrentSkipListMap也说它的迭代器和分配器是弱一致的。
https://stackoverflow.com/questions/49301523
复制相似问题