Fadensicherheitsimplikationen von Spring DI

8

Was sind in meinem erfundenen Beispiel die Auswirkungen auf die Thread-Sicherheit in Bezug auf die Liste der teamMembers?

Kann ich darauf vertrauen, dass der Status der Liste, wie er von der Methode run() angezeigt wird, konsistent ist?

Angenommen,

  1. Die Methode setATeamMembers wird nur einmal im Frühling aufgerufen, wenn sie die ATeamEpisode -Bohne erstellt

  2. Die Methode init wird von spring (init-method) nach # 1

  3. aufgerufen
  4. Die Klasse ATeamMember ist unveränderlich

    • Muss ich teamMembers volatile oder ähnlich deklarieren?

    • Gibt es noch andere scheußliche Probleme mit diesem Ansatz? übersieht?

Entschuldigung, wenn das offensichtlich ist, oder ein klarer Fehler bei rtfm

Danke und Grüße

Ed

%Vor%     
user591948 08.10.2012, 11:46
quelle

2 Antworten

5

Wenn, wie Sie sagen, setATeamMembers nur einmal aufgerufen wird und kein anderer Teil Ihres Codes diese Auflistung ersetzt, dann macht es keinen Sinn, sie flüchtig zu machen. Volatile gibt an, dass ein Member von verschiedenen Threads geschrieben sein kann.

Wenn auch kein Teil Ihres Codes diese Sammlung zu aktualisieren scheint, sollten Sie erwägen, die Sammlung explizit nicht änderbar zu machen, z. B. mit Collections.unmodiblicableList (). Dies macht es Ihnen und anderen klar, dass diese Sammlung nicht verändert wird und eine große fette Ausnahme in Ihr Gesicht wirft, wenn Sie versuchen, sie unabhängig zu ändern.

Die faule Initialisierung von Spring ist, AFAIR, threadsicher.

    
Nim 08.10.2012, 12:06
quelle
3

Vielleicht. Die List -Schnittstelle als solche ist nicht Thread-sicher und egal, was Sie tun, kann sie nicht threadsicher gemacht werden auf der Verbraucherseite .

Was Sie tun müssen, ist eine threadsichere Liste zu erstellen (die Java-Laufzeitumgebung hat einige Implementierungen) und Sie verwenden eine davon für die teamMembers -Bohne.

Der Zugriff auf die Bean über das Feld teamMembers ist kein Problem, da die anderen Threads keine neue Instanz erstellen, sondern den Status (dh die Daten innerhalb von) ändern. co_de% bean.

Also muss die Bean sicherstellen, dass Änderungen an ihrer internen Struktur korrekt synchronisiert sind.

In Ihrem Fall benötigen Sie eine spezielle Listenimplementierung, die ein zufälliges Element aus der Liste zurückgibt. Warum? Weil der Wert für teamMembers sich geändert haben kann, wenn teamMembers.size() aufgerufen wird.

Ein einfacher Weg, dies zu erreichen, besteht darin, alle Methodenaufrufe in diesen Code zu schreiben:

%Vor%

Aber Sie müssen sicher sein, dass Sie wirklich alle gefangen haben. Der einfachste Weg, um das zu erreichen, ist, wie ich bereits sagte, eine eigene Liste zu schreiben, die all die speziellen Methoden bietet, die Sie brauchen. Auf diese Weise können Sie nach Bedarf Sperren oder teamMembers.get() innerhalb der Methoden verwenden.

    
Aaron Digulla 08.10.2012 12:08
quelle