首页 文章

确保在迭代它时获取`ConcurrentHashMap`的所有值,而其他线程放置元素

提问于
浏览
0

我有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 回答

  • 0

    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 也说它的迭代器和分裂器是弱一致的 .

相关问题