我有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);
通过ConcurrentHashMap docs表明迭代 Map 实际上不是线程安全的 . 无法确保获得所有条目:
对于诸如putAll和clear之类的聚合操作,并发检索可能反映仅插入或删除某些条目 . 类似地,Iterators,Spliterators和Enumerations在迭代器/枚举的创建时或之后的某个时刻返回反映哈希表状态的元素 . 它们不会抛出ConcurrentModificationException .
在我迭代所有条目之前,是否有可能以某种方式等待或同步?
1 回答
ConcurrentHashMap.size()
的文档没有提供有关可见性效果的任何保证,它委托以下方法进行实际计数大概作为一个副作用,它使你的代码中的所有元素都可见,但这不是你应该依赖的东西(至少除非你理解
ConcurrentHashMap
的内部工作原理,否则我不这样做) .ConcurrentHashMap
的目的是提供线程安全的插入和检索,但我认为迭代以可靠的方式工作很难或不可能 . 我不知道任何标准Maps
也可以作为替换,另一个并发映射ConcurrentSkipListMap
也说它的迭代器和分裂器是弱一致的 .