Vorwort: Ich weiß, dass in den meisten Fällen mit einem volatilen Feld keine messbare Leistungseinbußen, aber diese Frage ist mehr theoretisch und zielgerichtet auf ein Design mit einem extrem hohe currency-Unterstützung.Java gleichzeitiger Zugriff auf Feld, Trick nicht flüchtig zu verwenden
Ich habe ein Feld, das eine List<Something>
ist, die nach der Erstellung gefüllt wird. Um etwas Leistung zu sparen, möchte ich die Liste in eine schreibgeschützte Map umwandeln. Wenn Sie dies zu einem beliebigen Zeitpunkt tun möchten, benötigen Sie mindestens ein flüchtiges Map-Feld, damit Änderungen für alle Threads sichtbar werden.
Ich dachte an den folgenden Aktionen ausführen:
Map map; public void get(Object key){ if(map==null){ Map temp = new Map(); for(Object value : super.getList()){ temp.put(value.getKey(),value); } map = temp; } return map.get(key); }
Dies könnte mehrere Threads verursacht die Karte selbst erzeugen, wenn sie den get-Block in einer serialisierten Weise eingeben. Dies wäre kein großes Problem, wenn Threads auf verschiedenen identischen Instanzen der Map arbeiten. Was mich mehr beunruhigt ist:
Ist es möglich, dass ein Thread die neue temporäre Karte dem Kartenfeld zuweist, und dann ein zweiter Thread sieht map!=null
und daher Zugriff auf das Kartenfeld, ohne eine neue, aber zu meiner Überraschung stellt fest, dass die Karte leer ist, weil die Put-Operationen noch nicht in einen gemeinsamen Speicherbereich verschoben wurden?
Antworten auf Kommentare:
- Die Fäden die temporäre Karte nach nur ändern, dass es nur gelesen wird.
- Ich muss eine Liste in eine Karte umwandeln wegen einer speziellen JAXB-Konfiguration, die es nicht möglich macht, eine Karte zu erstellen.
'volatile' können einige Kosten haben vor allem in Multi-Prozessor-Umgebungen. Es kann Speichersperren erfordern, um sicherzustellen, dass andere Threads Änderungen sehen. – seand
Können Sie erklären, wie/wann Threads welche Liste/Karte ändern und warum Sie eine Liste in eine Karte kopieren möchten? – zapl
Ich sehe kein Problem (andere, dass Ihr Code nicht kompilieren wird, kein Rückgabetyp) –