我有一个这样的代码片段:

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


我的问题是:是否需要使用如图所示的同步块,因为从keySet()到get()的操作不是原子的(因此,可以在一个调用与下一个调用之间更新映射,因为ConcurrentHashMap是每个调用仅具有线程安全性)?

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

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

预先感谢您的回复。

最佳答案

这取决于您需要的结果。

当前,如果在另一个线程中修改了infoMap,则在调用infonull很有可能是get-这将导致对NPE的调用中出现getName。如果这是必需的行为,或者您确信此方法是将修改Map的唯一位置,则只需synchronized就足够了。

使用EntrySet不会绕过问题-只会推迟它。所有要做的就是确保,如果在迭代过程中删除某个条目,则不会立即出现问题-但是显然,您可能返回的映射图中不再存在的数据。

10-06 14:29