Seien Sie gewarnt, dass auch in Single-Thread-Code, eine ConcurrentHashMap mit einer HashMap zu ersetzen möglicherweise nicht sicher sein. ConcurrentHashMap verbietet null als Schlüssel oder Wert. HashMap verbietet sie nicht (fragen Sie nicht).
In der unwahrscheinlichen Situation, dass Ihr vorhandener Code der Sammlung während der Einrichtung eine Null hinzufügt (vermutlich in einem Fehlerfall irgendeiner Art), wird das Ersetzen der Sammlung wie beschrieben das funktionale Verhalten ändern.
Das heißt, sofern Sie nichts anderes tun, sind gleichzeitige Lesevorgänge aus einer HashMap sicher.
[Bearbeiten: Mit "gleichzeitigen Lesevorgängen" meine ich, dass es nicht auch gleichzeitige Änderungen gibt.
Andere Antworten erläutern, wie dies sichergestellt werden kann. Eine Möglichkeit ist, die Map unveränderlich zu machen, aber das ist nicht notwendig. Das JSR133-Speichermodell definiert beispielsweise das Starten eines Threads ausdrücklich als synchronisierte Aktion, was bedeutet, dass Änderungen, die in Thread A vorgenommen werden, bevor dieser Thread B startet, in Thread B sichtbar sind.
Meine Absicht ist es nicht, diesen ausführlicheren Antworten über das Java-Speichermodell zu widersprechen. Diese Antwort soll darauf hinweisen, dass es, abgesehen von Gleichzeitigkeitsproblemen, mindestens einen API-Unterschied zwischen ConcurrentHashMap und HashMap gibt, der sogar ein Single-Thread-Programm zum Scheitern bringen könnte, das das eine durch das andere ersetzt].
4 Stimmen
Viele Antworten hier sind richtig in Bezug auf den gegenseitigen Ausschluss von laufenden Threads, aber falsch in Bezug auf Speicheraktualisierungen. Ich habe entsprechend hoch/runter gestimmt, aber es gibt immer noch viele falsche Antworten mit positiven Stimmen.
0 Stimmen
@Heath Borders, wenn die Instanz a statisch initialisiert wurde unmodifiable HashMap, sollte es sicher für gleichzeitiges Lesen sein (wie andere Threads nicht Updates verpasst haben könnte, da es keine Updates), richtig?
0 Stimmen
Wenn es statisch initialisiert und nie außerhalb des statischen Blocks geändert wird, dann könnte es in Ordnung sein, weil alle statischen Initialisierungen durch die Synchronisierung der
ClassLoader
. Das ist schon eine eigene Frage wert. Ich würde es trotzdem explizit synchronisieren und ein Profil erstellen, um zu überprüfen, ob es wirklich Leistungsprobleme verursacht.0 Stimmen
@HeathBorders - was meinen Sie mit "Speicheraktualisierungen"? Die JVM ist ein formales Modell, das Dinge wie Sichtbarkeit und Atomarität definiert, passiert-vor Beziehungen, verwendet aber keine Begriffe wie "Speicheraktualisierung". Sie sollten dies klären, vorzugsweise unter Verwendung der Terminologie aus dem JLS.
2 Stimmen
@Dave - Ich gehe davon aus, dass Sie nach 8 Jahren nicht immer noch auf der Suche nach einer Antwort sind, aber für das Protokoll, die Hauptverwirrung in fast allen Antworten ist, dass sie sich auf die Aktionen, die Sie auf dem Kartenobjekt durchführen . Sie haben bereits erklärt, dass Sie das Objekt nie verändern, also ist das alles irrelevant. Das einzige potenzielle "Problem" ist also wie Sie die Referenz veröffentlichen zum
Map
was Sie nicht erklärt haben. Wenn man es nicht sicher macht, ist es nicht sicher. Wenn Sie es sicher tun, es ist . Einzelheiten in meiner Antwort.