我有一个这样的代码段:
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(),则需要同步块,但我不确定。
提前感谢您的回复。
答案 0 :(得分:2)
这取决于您需要的结果。
目前,如果infoMap
在另一个帖子中被修改,info
很可能在调用null
时为get
- 这会导致NPE
1}}调用getName
。如果这是必需的行为,或者您确信此方法是唯一可以修改Map
的方法,那么只需synchronized
即可。
使用EntrySet
不会支持问题 - 它只会推迟它。所有将要实现的将是确保如果在迭代期间删除条目,您将不会立即出现问题 - 但显然您可能会返回不再在地图中的数据。
答案 1 :(得分:0)
在迭代HashMap的键和值时,应始终使用entrySet()方法。此外,在ConcurrentHashMap中,entrySet()将永远不会抛出&#34; ConcurrentModificationException&#34; (see Javadoc)