Heim  >  Artikel  >  Java  >  Wie löst man Thread-Sicherheitsprobleme im Java-Singleton-Muster?

Wie löst man Thread-Sicherheitsprobleme im Java-Singleton-Muster?

王林
王林nach vorne
2023-05-09 19:28:061477Durchsuche

    1 Zu berücksichtigende Faktoren bei der Verwendung von Multithreading

    Effizienz verbessern: # 🎜 🎜#Die Verwendung von Multithreading dient dazu, die CPU-Ressourcen voll auszunutzen und die Aufgabeneffizienz zu verbessern.
    Thread-Sicherheit: Das Grundlegendste bei der Verwendung von Multithreading ist die Gewährleistung der Thread-Sicherheit.#🎜 🎜#

    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.
    Feinkörniges Sperren : gesperrter Code. Etwas weniger, damit andere Codes gleichzeitig ausgeführt werden können Betreibt gemeinsam genutzte Variablen. Sicherheitsprobleme 🎜#


    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 erstellen

    Diese 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;
        }
    }

    2. Der Lazy-Modus funktioniert Erstellen Sie keine Instanz, wenn die Klasse geladen wird, sondern erstellen Sie sie nur beim ersten Mal, wenn sie verwendet wird Der obige Code hat keine Thread-Sicherheitsprobleme in einem einzelnen Thread, aber gibt es Sicherheitsprobleme in einer Multithread-Umgebung?


    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 aufrufen

    Ergebnis:

    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;
        }
    }

    Welche Probleme gibt es bei der Implementierung der Thread-Sicherheit auf diese Weise?

    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 ändern

    Implementierungscode:
    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

    Zeichnungsanalyse, wie unten gezeigt:

    3. Das Prinzip von volatile

    volatile 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?

    Ü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)
    optimieren

    Das Ergebnis dieser Neuordnung kann dazu führen, dass die Zuweisung abgeschlossen ist, bevor das Objekt instanziiert wird, nachdem der Speicherplatz zugewiesen wurde.
    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

    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)
    #🎜🎜 #

    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!

    Stellungnahme:
    Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen