2017-02-22 1 views
1

정적 블록에서 초기화 된 공유 해시 맵이있는이 코드를 사용합니다. 해시 맵을 공개하지 않으며 읽기 전용으로 사용됩니다 (get 및 containsKey). 이 스레드가 안전한지 확인하고 싶습니다.자바 해시 맵 읽기 전용 스레드 안전

public class MyClass { 
    private static final Map<String, MyObject> myMap; 

    static { 
     myMap = new MyLoader().load() 
    } 

    public MyClass() { 
     if (containsKey(someKey)) { 
      // do something 
     } 
     myMap.get(something) 
    } 

    static boolean containsKey(String key) { 
     // do some other stuff 
     return myMap.containsKey(key) 
    } 
} 
+0

다른 스레드가 읽는 동안 스레드를 맵 수정하는 중 (키/값 쌍을 추가 또는 제거하거나 기존 값을 변경)하는 스레드가없는 한 스레드로부터 안전합니다. 나는 스레딩과 상관없이 문제를 일으키기 때문에 키 객체를 변경하는 것을 포함하지 않았습니다. –

+0

노출되지 않고 클래스 내에서 수정되지 않았습니다. –

+0

메소드는 맵에 쓰는 전체 어플리케이션에서'new MyLoader(). load()'를 _only_ 것으로 호출합니까? 하나의 전화? –

답변

2

new MyLoader().load() 완전히 모든 데이터가 초기화되고있는 모든 스레드가 동시에이 맵에서 데이터를 검색하는 그 후, 다음 안전 수정되지 않습니다지도를 반환한다고 가정. HashMap 용 Javadoc은 "여러 스레드가 동시에 해시 맵에 액세스하고 스레드 중 하나 이상이 맵을 구조적으로 수정하면 외부에서 동기화되어야합니다." 따라서 맵을 수정중인 스레드가 없으면 동기화 할 필요가 없습니다. 안전을 위해

, 당신의 load() 방법은 불변성을 적용해야합니다

public Map<String, MyObject> load() { 
    Map<String, MyObject> mymap = new HashMap<>(); 
    mymap.put(...); 
    ... 
    return Collections.unmodifiableMap(mymap); 
} 

이 방법, 당신은 당신이 익숙하지 않은 일부 코드의 일부 스레드가 실수로지도를 수정할 수 있음을 걱정할 필요가 없습니다. 할 수 없을 것입니다.