2014-09-22 57 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)