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

时间:2018-03-15 14:02:46

标签: java concurrency hashmap

我有一个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表明迭代地图并不是真正的线程安全。无法确保获得所有条目:

  

对于诸如putAll和clear之类的聚合操作,并发检索可能反映仅插入或删除某些条目。类似地,Iterators,Spliterators和Enumerations在迭代器/枚举的创建时或之后的某个时刻返回反映哈希表状态的元素。它们不会抛出ConcurrentModificationException。

在迭代所有条目之前,是否有可能以某种方式等待或同步?

1 个答案:

答案 0 :(得分: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的内部运作,否则我会&#39 ; t)的

ConcurrentHashMap的目的是提供线程安全的插入和检索,但我认为迭代以可靠的方式工作很难或不可能。我不知道任何标准Maps也可以替代,另一个并发映射ConcurrentSkipListMap也表示其迭代器和分裂器弱一致。< / p>