2017-02-22 4 views
1

Ich habe diesen Code, dass eine gemeinsame Hash-Karte in statischem Block initialisiert. Ich stelle die hashmap nicht zur Verfügung und es wird nur gelesen (get und containKey). Ich wollte sicherstellen, dass dies Thread-sicher ist.Java hashmap Nur-Lese-Thread-Sicherheit

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

Solange kein Gewinde die Karte Modifizieren (Hinzufügen oder ein Schlüssel/Wert-Paar zu entfernen, oder einen vorhandenen Wert mutiert), während andere Threads lesen, dann ist es threadsicher. Ich habe kein Schlüsselobjekt mutiert, da dies unabhängig vom Threading zu Problemen führt. –

+0

Es ist nicht ausgesetzt zu sein und es nicht innerhalb der Klasse geändert –

+0

ist die Methode Aufruf 'neue MyLoader(). Load()' die _only_ Sache in der ganzen Anwendung, die auf die Karte schreibt, und tut es immer nur, dass schreibt es ein Anruf? –

Antwort

2

Unter der Annahme, dass new MyLoader().load() Karte zurückgibt, die vollständig mit allen Daten initialisiert wird und bei dem es nie danach geändert wird, dann ist es sicher für alle Threads Daten von dieser Karte gleichzeitig abzurufen. Das Javadoc for HashMap sagt: "Wenn mehrere Threads gleichzeitig auf eine Hash-Map zugreifen und mindestens einer der Threads die Map strukturell ändert, muss sie extern synchronisiert werden." Wenn also kein Thread die Map ändert, muss sie nicht synchronisiert werden.

Als Sicherheitsmaßnahme, Ihre load() Methode Unveränderlichkeit erzwingen sollte:

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

Auf diese Weise, Sie müssen nicht befürchten, dass einige Thread mit Ihnen nicht vertraut sind in einigen Code versehentlich die Karte ändern könnten. Es wird nicht möglich sein.