Ich weiß jedoch auch, dass Benutzer sich meistens nur um eine Teilmenge der gespeicherten Daten kümmern, sodass sie intern träge initialisiert werden: Beim ersten Zugriff auf jedes Feld werden die Daten berechnet und für zukünftige Verwendungen gespeichert.
In einigen wenigen Fällen kann es für Benutzer nützlich sein, diese Datenstrukturen beizubehalten und zu teilen sie zwischen Threads. So wie es aussieht, ist dies eindeutig unsicher, da die verzögerte Initialisierungslogik voller Check-then-Act-Probleme sein wird.
Ich sehe die folgenden Lösungen:
- Duplizieren Sie die Klassen in echte unveränderliche Alternativen. Da die Hierarchie ziemlich groß und komplex ist, würde ich es lieber vermeiden, das alles pflegen zu müssen.
- Eine Möglichkeit finden, die Datenstruktur einzufrieren, so dass sie anschließend wirklich unveränderlich ist. Zum Glück ist das dasselbe wie eine eifrige Initialisierung von allem.
Code: Select all
public class DataStructure {
private final Map cache = new LinkedHashMap();
public Datum get(index i) { … }
public int size() { … }
public void eager() {
for (int i = 0; i < size(); i++)
get(i);
}
}
Ich lese jedoch „Java Concurrency in Practice“ und dort wird erwähnt, dass die sichere Veröffentlichung über finale-Felder erfolgt. In dieser Klasse gibt es keine finalen-Felder.
Ist diese Klasse threadsicher, nachdem eifrig() aufgerufen wurde? Wenn dies nicht der Fall ist, wie kann ich es so ändern, ohne Kosten für den Happy-Path zu zahlen, bei dem Eager() niemals aufgerufen wird und Thread-Sicherheit nicht erforderlich ist?
Mobile version