Heim >Java >javaLernprogramm >Wie löst man Thread-Sicherheitsprobleme im Java-Singleton-Muster?
Feinkörniges Sperren : gesperrter Code. Etwas weniger, damit andere Codes gleichzeitig ausgeführt werden können Betreibt gemeinsam genutzte Variablen. Sicherheitsprobleme 🎜#Effizienz verbessern: # 🎜 🎜#Die Verwendung von Multithreading dient dazu, die CPU-Ressourcen voll auszunutzen und die Aufgabeneffizienz zu verbessern.
Wenn wir also Multithread-Code entwerfen, müssen wir die Effizienz der Aufgabenausführung so weit wie möglich verbessern und gleichzeitig die Thread-Sicherheit gewährleisten.
Thread-Sicherheit: Das Grundlegendste bei der Verwendung von Multithreading ist die Gewährleistung der Thread-Sicherheit.#🎜 🎜#
Der Singleton-Modus kann sicherstellen, dass nur eine Instanz einer bestimmten Klasse im Programm vorhanden ist, ohne dass mehrere Instanzen erstellt werden müssen.
Zum Beispiel: DataSource (Datenverbindungspool), eine Datenbank benötigt nur eine Verbindungspoolobjekt
Der Singleton-Modus ist in den Hungrigen Modus und den Lazy-Modus unterteilt
1 🎜🎜#Der Hungrige Modus besteht darin, beim Laden der Klasse eine Instanz zu erstellenDiese Methode ist threadsicher (JVM verwendet intern Sperren, d Erstellung, nur einmal ausgeführt)
Implementierungscode:
public class Singleton { private static Singleton instance = new Singleton(); private Singleton(){ } public static Singleton getInstance(){ return instance; } }
Analyse:
Wenn die Instanz nicht erstellt wird und mehrere Threads die getInstance-Methode aufrufen, ist es möglich, mehrere zu erstellen Instanzen verursachen Thread-Sicherheitsprobleme
Aber sobald die Instanz erstellt ist, gibt es keine Thread-Sicherheitsprobleme, wenn nachfolgende Threads die getInstance-Methode aufrufenErgebnis:Welche Probleme gibt es bei der Implementierung der Thread-Sicherheit auf diese Weise?Thread Sicherheitsprobleme treten auf, wenn eine Instanz zum ersten Mal erstellt wird. ????️Der Code lautet wie folgt:
public class Singleton { private static Singleton instance = null; private Singleton(){ } public static Singleton getInstance(){ if(instance == null){ instance = new Singleton(); } return instance; } }
Analyse: Wir verwenden synchronisierte Änderungen an der Methode, dh jedes Mal, wenn die Methode aufgerufen wird, wird die Sperre aktiviert wird konkurriert. Sie müssen jedoch nur einmal eine Instanz erstellen, d. h. nach dem Aufruf dieser Methode muss um die Sperre konkurriert werden, um die Sperre aufzuheben. Lazy-Modus (verbessert durch die Verwendung einer doppelten Prüfsperre)
Nehmen Sie Änderungen basierend auf dem obigen Code vor:
# 🎜🎜#Verwenden Sie die doppelte Beurteilung, um die Häufigkeit von Wettbewerbssperren zu reduzieren#🎜🎜 #Verwenden Sie flüchtig, um die Instanz zu ändernImplementierungscode:
Zeichnungsanalyse, wie unten gezeigt:public class Singleton { private static Singleton instance = null; private Singleton(){ } public static synchronized Singleton getInstance(){ if(instance == null){ instance = new Singleton(); } return instance; } }Für doppelte Analyse von if:
Äußere Ebene, wenn Beurteilung:
#🎜 🎜#Die Instanz wird nur einmal erstellt. Fahren Sie nicht fort, sondern kehren Sie direkt zurück wenn Urteil: Wenn die Instanz nicht erstellt wird, konkurrieren mehrere Threads gleichzeitig um die Sperre und die anderen Threads konkurrieren nicht Der erste Thread gibt die Sperre frei, diese fehlgeschlagenen Threads konkurrieren weiterhin, aber die Instanz wurde erstellt, sodass die obige Beurteilung erneut erfolgen muss
3. Das Prinzip von volatilevolatile sorgt für Sichtbarkeit und Ordnung Auf der Java-Ebene ist volatile Eine sperrenfreie Operation. Mehrere Threads können flüchtig geänderte Variablen gleichzeitig lesen und parallel ausführen, was fast genauso effizient ist wie die sperrenfreie Ausführung, CPU-Auslastung Das Protokoll wird verwendet, um sicherzustellen, dass die neuesten Hauptspeicherdaten gelesen werden Variable, Sie müssen sie erneut aus dem Hauptspeicher lesen garantiert keine Ordnung. Stimmt etwas mit der Art und Weise, wie Double-Check-Sperren geschrieben werden?
optimierenÜber das neue Objekt ist es der Reihe nach in drei Anweisungen unterteilt:
(1) Weisen Sie den Speicherplatz des Objekts zu #🎜 🎜#(2) Instanziieren Sie das Objekt(3) und weisen Sie es der Variablen zu
Die normale Ausführungsreihenfolge ist (1)(2)(3), die JVM kann die neu geordnete Reihenfolge für (1)(3)(2)
#🎜🎜 #Das Ergebnis dieser Neuordnung kann dazu führen, dass die Zuweisung abgeschlossen ist, bevor das Objekt instanziiert wird, nachdem der Speicherplatz zugewiesen wurde.
In der CPU betriebsbasiert Bei flüchtigen Variablen gibt es einen Sperrmechanismus auf CPU-Ebene (er stellt sicher, dass (1)(2)(3) alle ausgeführt und in den Hauptspeicher zurückgeschrieben werden und dann andere Threads Operationen an den Variablen ausführen)
Nach dieser falschen Zuweisung wird Instanz == Null nicht erstellt. und der Thread wird die Instanz enthalten, die nicht instanziiert wurde, und bei der Verwendung seiner Eigenschaften und Methoden tritt ein Fehler auf 🎜##🎜🎜 #Egal in welcher Reihenfolge (1)(2)(3) der Thread ein neues Objekt erstellt, die vom nachfolgenden Thread erhaltene Instanz wurde instanziiert
Das obige ist der detaillierte Inhalt vonWie löst man Thread-Sicherheitsprobleme im Java-Singleton-Muster?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!