Heim  >  Artikel  >  Java  >  Einführung in die Verwendung des synchronisierten Schlüsselworts in Java (Codebeispiel)

Einführung in die Verwendung des synchronisierten Schlüsselworts in Java (Codebeispiel)

不言
不言nach vorne
2019-01-30 11:21:013707Durchsuche

Dieser Artikel bietet Ihnen eine Einführung in die Verwendung des synchronisierten Schlüsselworts in Java (Codebeispiele). Ich hoffe, dass es einen gewissen Referenzwert hat es wird Ihnen hilfreich sein.

Bei der gleichzeitigen Programmierung spielt das synchronisierte Schlüsselwort eine häufige Rolle. Früher nannten wir das synchronisierte Schlüsselwort „Weight Lock“, aber „synchonized“ wurde in JDK1.6 optimiert und es wurden voreingenommene Sperren und leichte Sperren eingeführt. In diesem Artikel werden die Verwendung des synchronisierten Schlüsselworts sowie die Unterschiede und Implementierungsprinzipien von Bias-Sperren, leichten Sperren und schweren Sperren vorgestellt.

Sehen wir uns zunächst die vier Verwendungsmöglichkeiten des synchronisierten Schlüsselworts an.

1. Gewöhnliche Methoden ändern

private synchronized void synMethod(){
}

In dieser Verwendung Objekt Instanz einer synchronisierten Sperre.

2. Statische Methoden ändern

private static synchronized void synMethod(){
}

synchronisiert In diesem Fall ist die Sperre das aktuelle Klassenobjekt.

3. Synchroner Methodenblock

private  void synMethod1(){
        synchronized(this){
            
        }
    }    
    private  void synMethod2(){
        synchronized(ThreadTest.class){
            
        }
    }

Objektinstanz in synMethod1 sperren; das aktuelle Klassenobjekt.

Einführung in das Sperrprinzip

Bevor wir das Sperrprinzip einführen, lernen wir zunächst den Java-Objektheader Mark Word kennen, der 32-Bit verwendet als Beispiel.

Sperrstatus

25 Bit

4bit

1bit

2bit

 

23bit

2bit

Ob es in Richtung Sperre voreingenommen ist

Sperrflagge

Leichtes Schloss

Zeiger auf den Sperrdatensatz im Stapel

0

Schwergewichtsschloss

Zeiger auf Mutex (Schwergewichtssperre)

10

GCMarkieren

Leer

11

Bias-Sperre

ThreadID

Epoche

Alter der Objektgenerierung

1

01

Lockless

HashCode des Objekts

Alter der Objektgenerierung

0

01

Die obige Tabelle beschreibt die im Objektheader gespeicherten Informationen, wenn sich das Objekt in jedem Sperrstatus befindet.

1. Voreingenommene Sperre

Wenn in der tatsächlichen Umgebung ein Thread auf einen synchronisierten Block zugreift und kein anderer Thread um die Sperre konkurriert, und Derselbe Thread erhält die Sperre mehrmals, d. h. ein einzelner Thread führt den Synchronisationscode aus. Wenn der Thread in diesem Fall jedes Mal blockiert wird, bedeutet dies eine Verschwendung von CPU-Leistung. In diesem Fall wird das Konzept der vorgespannten Verriegelung eingeführt.

  • Zugriff auf synchronisierten Codeblock

  • Bestimmen Sie, ob die im Objektheader Mark Word gespeicherte Thread-ID auf den aktuellen Thread verweist. Wenn dies der Fall ist, bedeutet dies, dass die aktuelle Sperre nicht erforderlich ist, und führen Sie die Synchronisierung nicht direkt aus Code

  • Wenn nicht, versuchen Sie, den CAS-Algorithmus zu verwenden, um die Thread-ID im Objektheader zu aktualisieren.

  • Erhält erfolgreich die Sperre und führt den Synchronisierungscode aus. Wenn die Aktualisierung fehlschlägt, bedeutet dies, dass eine Sperrenkonkurrenz vorliegt. Warten Sie auf den globalen Sicherheitspunkt, halten Sie den Thread an, der die voreingenommene Sperre besitzt, und entscheiden Sie sich dafür, die voreingenommene Sperre auf eine leichte Sperre zu aktualisieren oder sie gemäß dem Sperrflag in auf keine Sperre zu setzen Objekt-Header.

Sie können -XX:-userBiasedLocking=false verwenden, um die voreingenommene JVM-Sperroptimierung zu deaktivieren und die Lightweight-Sperre standardmäßig direkt einzugeben.

2. Leichte Sperre

  • Zugriff auf den Synchronisierungscodeblock Erstellen Sie zunächst einen Sperrdatensatzbereich (Lock Record) im Thread-Stapel des aktuellen Threads.

  • Kopieren Sie den Objektheader Mark Word in den Sperrdatensatz.

  • Verwenden Sie CAS, um zu versuchen, den Thread-Zeiger im Objektheader Mark Word auf einen Zeiger auf den aktuellen Thread zu aktualisieren

  • Wenn die Aktualisierung erfolgt Erfolgreich erhalten Sie ein leichtes Schloss.

  • Aktualisierung fehlgeschlagen. Überprüfen Sie, ob der Zeiger in Mark Word auf den aktuellen Thread zeigt.

  • Wenn ja, bedeutet dies einen Wiedereintritt in die Sperre. Synchronisierten Codeblock ausführen

  • Wenn nicht, bedeutet dies, dass derzeit Konkurrenz besteht. Leichte Schlösser müssen zu Gewichtsschlössern erweitert werden.

3. Gewichtssperre

Die Gewichtssperre wird auf Basis des Objektmonitors (Monitor) implementiert.

Wenn ein Thread Synchronisationscode ausführt, muss er eine Monitor.enter-Anweisung aufrufen. Rufen Sie nach Beendigung der Ausführung die Anweisung „Monitor.exit“ auf. Hier ist ersichtlich, dass der Monitor exklusiv ist. Es kann jeweils nur ein Thread erfolgreich eingegeben werden und andere Threads können nur in der Warteschlange blockiert werden. Daher ist der Betrieb dieser Gewichtssperre sehr teuer.

Das obige ist der detaillierte Inhalt vonEinführung in die Verwendung des synchronisierten Schlüsselworts in Java (Codebeispiel). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

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