2011-05-04 2 views
2

두 스레드를 통해 동기화하려고하는 맵 내의 맵 내에 중첩 세트가 있습니다.중첩 된 맵 및 세트 동기화 (Java)

지도는 같은 인스턴스화 : 이것은 내가지도에 값을 추가 할 수있는 기능입니다

private final Map<Manageable, Map<String, Set<Manageable>>> manageableMap = 
     Collections.synchronizedMap(new HashMap<Manageable, Map<String, Set<Manageable>>>()); 

:

private void put(Manageable key, Manageable value, String valueType) { 
    synchronized (manageableMap) { 
     Map<String, Set<Manageable>> setMap = manageableMap.get(key); 
     if (setMap == null) { 
      setMap = new HashMap<String, Set<Manageable>>(); 
      manageableMap.put(key, Collections.synchronizedMap(setMap)); 
     } 

     synchronized (setMap) { 
      Set<Manageable> set = setMap.get(valueType); 
      if (set == null) { 
       set = new HashSet<Manageable>(); 
       setMap.put(valueType, Collections.synchronizedSet(set)); 
      } 

      synchronized (set) { 
       set.add(value); 
      } 
     } 
    } 
} 

하게 IntelliJ IDEA 내가 로컬 변수에 동기화하고 나에게 경고를하는 setMap 설정합니다.

나는 동기화에 상당히 익숙하며이 방법이 중첩 된 데이터 구조를 동기화하는 적절한 방법인지 궁금합니다.

도움 주셔서 감사합니다.

답변

3

관리 가능한지도 만 동기화하면됩니다. 한 번에 오직 하나의 스레드 만 manageableMap에 대한 잠금을 획득 할 수 있으므로 스레드가 manageableMap에 대한 잠금을 획득 한 경우 set 및 setMap에 대한 추가 잠금이 필요하지 않습니다. 단 하나의 스레드 (manageableMap을 잠근 스레드)가 set 및 setMap .

+0

동의 ... ..... – Bozho

+0

답장을 보내 주셔서 감사합니다. 나는 아직도이 동기화하는 것에 익숙해있다. 다른 시간에 동기화 된 블록을 사용해야합니까? – miningold

+0

복잡한 주제입니다. 이 책은 더 배우기를 원할 때 훌륭한 책입니다. http://www.amazon.com/Java-Concurrency-Practice-Brian-Goetz/dp/0321349601 – sbridges

1

동기화는 특정 개체 인스턴스에 대한 참조가 아닌 필드 또는 변수에 대한 참조를 포함하므로 동기화는 로컬 변수로만 반환되는지 여부에 관계없이 동일한 개체 인스턴스에서 발생해야합니다.

IDEA는 코드가 원하는대로 코드를 수행하는지 정적으로 확인할 수 없기 때문에 경고는 '코드 냄새'일 뿐이므로 효과가 예상과 다를 수 있음을 경고합니다.

가장 좋은 방법은 동기화하려는 인스턴스를 로그 아웃하고 코드가 예상 한 것인지 확인하여 코드를 테스트하는 것입니다. IDEA는 디버깅 중에 객체 인스턴스를 표시하여 동기화하는 객체 동일하거나 다른 인스턴스입니다.

1

항상 동기화를 수동으로 제어하는 ​​경우 Collections.synchronizedMap을 사용할 필요가 없을 것입니다. 목표 맵에서 동기화 된 하나의 섹션이 수행합니다.

+0

더 효율적이라고 말할 수있는 방법은 무엇입니까? synchronizedMap 또는 Synchronized 블록? – miningold

+0

synchronizedMap에는 래핑 된 맵에 위임 한 모든 작업에서 synchronized (this)가 포함됩니다. 이 메소드가 맵에 요소를 추가하는 유일한 장소이면 synchronizedMap (일반 맵)을 사용할 필요가 없습니다. 성능에 관해서는 평범한 맵을 가진 버전은 사용 패턴에 따라 무시할만큼 효율적입니다. – mrembisz