我有一个这样的代码片段:
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
,则在调用info
时null
很有可能是get
-这将导致对NPE
的调用中出现getName
。如果这是必需的行为,或者您确信此方法是将修改Map
的唯一位置,则只需synchronized
就足够了。
使用EntrySet
不会绕过问题-只会推迟它。所有要做的就是确保,如果在迭代过程中删除某个条目,则不会立即出现问题-但是显然,您可能返回的映射图中不再存在的数据。