迭代ConcurrentHashMap后使用get()

时间:2014-09-22 15:01:11

标签: java collections concurrenthashmap

我有一个这样的代码段:

    private final Map<String, Information> infoMap = new ConcurrentHashMap<String, Information>();

    synchronized (infoMap) {
        for (final String nameAndVersion : infoMap.keySet()) {
            final Information info = infoMap.get(nameAndVersion);
            final String name = info.getName();
            names.add(name);
        }
    }

我遇到的问题是:是否有必要使用如图所示的synchronized块,因为从keySet()到get()的操作不是原子的(因此可以在一个调用和下一个调用之间更新映射,因为对于每个单独的调用,ConcurrentHashMap只是线程安全的吗?

我是否应该迭代EntrySet,以确保构造完整的迭代器?

我相信如果调用keySet()和get(),则需要同步块,但我不确定。

提前感谢您的回复。

2 个答案:

答案 0 :(得分:2)

这取决于您需要的结果。

目前,如果infoMap在另一个帖子中被修改,info很可能在调用null时为get - 这会导致NPE 1}}调用getName。如果这是必需的行为,或者您确信此方法是唯一可以修改Map的方法,那么只需synchronized即可。

使用EntrySet不会支持问题 - 它只会推迟它。所有将要实现的将是确保如果在迭代期间删除条目,您将不会立即出现问题 - 但显然您可能会返回不再在地图中的数据。

答案 1 :(得分:0)

在迭代HashMap的键和值时,应始终使用entrySet()方法。此外,在ConcurrentHashMap中,entrySet()将永远不会抛出&#34; ConcurrentModificationException&#34; (see Javadoc)