2014-09-22 3 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); 
     } 
    } 

내가 가진 질문은 : 그림과 같이 필요한 keySet 반환의 작업으로, 동기화 된 블록을 사용하는 것입니다() get()는 원 자성이 아닙니다. 따라서 ConcurrentHashMap은 각 개별 호출에 대해서만 스레드 안전성을 가지므로 맵은 한 호출과 다음 호출 사이에서 업데이트 될 수 있습니다.

완전한 반복자가 생성되도록 EntrySet을 반복해야합니까?

keySet() 및 get()이 호출되면 동기화 블록이 필요하다고 생각하지만이 점에 대해서는 확신하지 못합니다.

미리 답변 해 주셔서 감사합니다.

답변

2

이것은 결과에 따라 다릅니다. getName의 통화에 발생하는 NPE을 일으킬 것이다 - infoMap 다른 스레드에서 수정되는 경우 infoget가 호출 될 때 null 될 수 있도록

현재, 그것은 아주 가능하다. 이것이 필요한 동작이거나이 방법이 유일한 장소 인 것으로 확신하는 경우 Map을 수정하면 synchronized이면 충분합니다.

EntrySet을 사용하면 문제가 해결되지 않으며 문제가 해결되지 않습니다. 달성하는 모든 일은 반복되는 동안 엔트리가 제거되면 즉각적인 문제를 제시하지 않도록 보장합니다. 그러나 더 이상지도에없는 데이터를 반환 할 수 있습니다.

0

HashMap의 키와 값을 반복 할 때는 항상 entrySet() 메소드를 사용해야합니다. 게다가 ConcurrentHashMap에서 entrySet()은 결코 "ConcurrentModificationException"을 throw하지 않습니다. (see Javadoc)

관련 문제