2014-09-22 84 views
1

后使用GET()我有一个代码段是这样的:迭代的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); 
     } 
    } 

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

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

我相信如果keySet()和get()被调用,需要synchonized块,但我不确定这一点。

在此先感谢您的回复。

回答

2

这取决于你需要的结果。

当前,如果infoMap在另一个线程被修改,它很可能为infonullget被称为 - 这将在电话会议中getName引起NPE。如果这是所需的行为,或者您确信此方法是Map将被修改的唯一位置,则只需​​就足够了。

使用EntrySet不会导致问题 - 它只会推迟它。所有将实现的目的都是为了确保在迭代过程中删除条目时,您不会遇到即时问题 - 但显然您可能会返回不再位于地图中的数据。

0

在迭代HashMap的键和值时,应始终使用entrySet()方法。而且在ConcurrentHashMap中,entrySet()永远不会抛出“ConcurrentModificationException”(see Javadoc)