在其他线程放置元素的同时进行迭代时,请确保获取`ConcurrentHashMap`的所有值. [英] Ensure to get all values of `ConcurrentHashMap` when iterating over it while other threads put elements

查看:88
本文介绍了在其他线程放置元素的同时进行迭代时,请确保获取`ConcurrentHashMap`的所有值.的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 ConcurrentHashMap 由8个不同的线程填充 put .8个线程之一尝试使用 forEach 使用者进行读取.我的问题是, ConcurrentHashMap 仅具有5-7个条目.

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);

如果我添加 map.size() 出于某种原因,它会显示所有8个条目

If I add a map.size() it for some reason shows all 8 entries

map.put(myContent);
map.size();
...
map.forEach(element -> ... do something);

浏览 ConcurrentHashMap docs 显示,迭代地图并不是真正的线程安全.不能确保获取所有条目:

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:

对于聚合操作(如putAll和clear),并发检索可能仅反映某些条目的插入或删除.同样,迭代器,拆分器和枚举返回的元素反映了在创建迭代器/枚举时或此后某个时刻哈希表的状态.他们不抛出ConcurrentModificationException.

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?

推荐答案

ConcurrentHashMap.size()的文档未提供有关可见性影响的任何保证,它委托了以下方法,实际计数

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;
}

作为副作用,它可能会使所有元素在代码中可见,但这不是您应该依赖的内容(至少除非您了解 ConcurrentHashMap 的内部工作原理,否则我不会)

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).

ConcurrentHashMap 的目的是提供线程安全的插入和检索,但是我想让迭代以可靠的方式工作是困难的或不可能的.我也不知道有任何标准的 Maps 可以替代,另外一个并发的地图 ConcurrentSkipListMap 也说它的迭代器和拆分器弱一致em>.

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.

这篇关于在其他线程放置元素的同时进行迭代时,请确保获取`ConcurrentHashMap`的所有值.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆