Ich erinnere mich, als ich anfing, Java zu lernen, wurde synchronisiert, als ich auf eine Multi-Threading-Situation stieß. Im Vergleich zu dieser Zeit war Synchron so magisch und kraftvoll. Zu dieser Zeit gaben wir ihm einen Namen "Synchronisation", der uns auch für uns zu einem guten Medikament zur Lösung von Multi-Threading-Situationen wurde. Aber wie wir erfahren, wissen wir, dass Synchronized ein Schwergewichtsschloss ist und es im Verhältnis zum Schloss so sperrig erscheint, dass wir der Meinung sind, dass es nicht so effizient ist und es langsam aufgibt.
Zugegeben, mit den verschiedenen Optimierungen von Javas SE 1.6 auf synchronisiertem Synchronized erscheinen nicht so schwer. Nachfolgend folgen Sie LZ, um den Implementierungsmechanismus von synchronisiertem Synchron zu untersuchen, wie Java es optimiert, den Mechanismus des Sperroptimierungsmechanismus, die Sperrspeicherstruktur und den Upgrade -Prozess optimiert.
Implementierungsprinzip
Synchronisiert kann sicherstellen, dass die Methode oder der Codeblock ausgeführt werden und nur eine Methode gleichzeitig den kritischen Bereich eingeben kann. Gleichzeitig kann es auch die Speichersichtbarkeit gemeinsamer Variablen sicherstellen.
Jedes Objekt in Java kann als Schloss verwendet werden, was die Grundlage für die Synchronisierung zur Implementierung der Synchronisation darstellt:
Gemeinsame Synchronisationsmethode ist die statische Synchronisationsmethode des aktuellen Instanzobjekts, Sperle ist der aktuelle Klassenobjekt -Synchronisierungsmethodenblock. Sperle ist das Objekt in Klammern, wenn ein Thread auf den Synchronisationscode -Block zugreift. Er muss zunächst die Sperre zum Ausführen des Synchronisierungscodes abrufen. Wenn eine Ausnahme ausgelöst oder ausgeworfen wird, muss das Schloss freigegeben werden. Wie implementiert es diesen Mechanismus? Schauen wir uns zuerst einen einfachen Code an:
öffentliche Klasse SynchronizedTest {public Synchronisierte void test1 () {} public void test2 () {synchronisiert (this) {}}}Verwenden Sie Javap Tool, um die generierten Klassendateisinformationen anzuzeigen, um die Implementierung von Synchronize zu analysieren
Wie aus den oben genannten Erscheinen ersichtlich ist, wird der Synchronisationscode -Block unter Verwendung von Monitenter- und Monitorexit -Anweisungen implementiert. Die Synchronisierungsmethode (sie zeigt nicht, dass Sie sich die zugrunde liegende JVM -Implementierung ansehen müssen) basiert auf der ACC_SYNCHRONISCHE -Implementierung im Methodenmodifikator.
Synchroncode -Block: Der MonitorEnter -Befehl wird in die Startposition des Synchronisationscodeblocks eingefügt, und der Monitorexit -Befehl wird in die Endposition des Synchronisationscodeblocks eingefügt. Das JVM muss sicherstellen, dass jeder Monitor einen Monitorexit entspricht. Jedes Objekt hat einen Monitor zugeordnet, und wenn ein Monitor gehalten wird, wird er gesperrt. Wenn ein Thread den MonitorEnter -Befehl ausführt, wird versucht, das dem Objekt entsprechende Überwachungsbesitz zu erhalten, dh versuchen, die Sperre des Objekts zu erhalten.
Synchronisierte Methode: Die synchronisierte Methode wird in ordentliche Methodenaufrufe und Rückgabebehörungen wie: InvokeVirtual- und Areturn -Anweisungen übersetzt. Auf der VM -Bytecode -Ebene gibt es keine speziellen Anweisungen zur Implementierung der synchronisierten modifizierten Methode. Stattdessen wird die synchronisierte Flagsposition 1 im Feld Methode Access_flags der Methode in der Methode -Tabelle der Klassendatei platziert, die angibt, dass die Methode eine synchronisierte Methode ist und das Objekt verwendet, das die Methode oder die Klasse der Methode zur Darstellung von KLASS als Sperrobjekt aufruft (siehe: http://www.vevb.com/article/129245.htm)
Lassen Sie es uns weiterhin analysieren, aber bevor wir tiefer gehen, müssen wir zwei wichtige Konzepte verstehen: Java -Objekt -Header und Monitor.
Java -Objektheader, Monitor
Java -Objekt -Header und -Monitore sind die Grundlage für die Implementierung von Synchron! Das Folgende ist eine detaillierte Einführung in diese beiden Konzepte.
Java -Objektkopf
Das für die Synchronisierung verwendete Schloss befindet sich im Java -Objekt -Header. Was ist also der Java -Objekt -Header? Der Objektheader der virtuellen Hotspot -Maschine enthält hauptsächlich zwei Teile Daten: markieren Sie Word (markiertes Feld) und KLASS -Zeiger (Typ Zeiger). Klass Point ist ein Zeiger auf die Klassenmetadaten des Objekts. Die virtuelle Maschine verwendet diesen Zeiger, um zu bestimmen, welche Klasseninstanz das Objekt ist. Mark Word wird verwendet, um die eigenen Laufzeitdaten des Objekts zu speichern. Es ist der Schlüssel zur Implementierung leichter Schlösser und voreingenommener Schlösser, sodass sich Folgendes darauf konzentriert.
Mark Wort markieren.
Mark Word wird verwendet, um die Laufzeitdaten des Objekts selbst zu speichern, z. JVM Virtual Machine kann die Größe des Java -Objekts über die Metadateninformationen des Java -Objekts bestimmen, kann jedoch nicht die Größe des Arrays aus den Metadaten des Arrays bestätigen, sodass ein Stück zur Aufzeichnung der Länge des Arrays verwendet wird. Die folgende Abbildung ist die Speicherstruktur des Java-Objekt-Headers (32-Bit-virtuelle Maschine):
Objekt -Header -Informationen sind zusätzliche Speicherkosten, die von den vom Objekt selbst definierten Daten unabhängig sind. In Anbetracht der räumlichen Effizienz der virtuellen Maschine ist Mark Word jedoch als nicht fixierte Datenstruktur ausgelegt, um so viele Daten wie möglich in einem sehr kleinen Speicherspeicher zu speichern. Es wird seinen eigenen Speicherplatz gemäß dem Zustand des Objekts wiederverwenden. Das heißt, Mark Word ändert sich mit dem Betrieb des Programms, und der Änderungsstatus lautet wie folgt (32-Bit-virtuelle Maschine):
Eine kurze Einführung in Java -Objekt -Header, schauen wir uns den Monitor an.
Monitor
Was ist Monitor? Wir können es als Synchronisationswerkzeug oder Synchronisationsmechanismus verstehen, der normalerweise als Objekt beschrieben wird.
Genau wie alles ein Objekt ist, sind alle Java -Objekte Naturmonitore, und jedes Java -Objekt kann ein Monitor werden, da im Java -Design jedes Java -Objekt ein unsichtbares Schloss trägt, da es aus dem Mutterleib herauskommt. Es wird als internes Schloss oder Überwachungsschloss bezeichnet.
Monitor ist eine Datenstruktur in Privatstruktur von Threads. Jeder Thread verfügt über eine Liste der verfügbaren Monitor -Datensätze und eine globale verfügbare Liste. Jedes gesperrte Objekt wird einem Monitor zugeordnet (Sperrenwort im Markwort der Objektkopfpunkte auf die Startadresse des Monitors). Gleichzeitig befindet sich ein Eigentümerfeld im Monitor, der die eindeutige Kennung des Fadens speichert, der das Schloss besitzt, und angibt, dass das Schloss vom Faden besetzt ist. Seine Struktur ist wie folgt:
Besitzer: Null am Anfang bedeutet, dass kein Thread derzeit das Monitorrecord besitzt. Wenn der Thread das Schloss erfolgreich besitzt, speichert er die eindeutige Identität des Threads, und wenn das Schloss freigegeben wird, wird er auf null gesetzt.
Eintrag: Associate a System Mutex (Semaphor), um alle Threads zu blockieren, die versuchen, Monitorrecord zu sperren.
Rcthis: repräsentiert die Anzahl aller Threads, die blockiert sind oder auf das Monitorrecord warten.
NEST: Wird verwendet, um die Zählung von Wiedereintrittsschlössern zu implementieren.
HashCode: Speichert den HashCode -Wert, der aus dem Objektkopf kopiert wird (kann auch GCAGE enthalten).
Kandidat: Wird verwendet, um unnötiges Blockieren zu vermeiden oder darauf zu warten, dass Threads aufwachen, da nur ein Thread das Schloss jedes Mal erfolgreich besitzen kann. Wenn der vorherige Thread, der das Schloss veröffentlichen, jedes Mal alle blockierenden oder wartenden Fäden aufweckt, führt dies zu unnötigem Kontextschalter (von der Blockierung bis zur Bereitschaft und dann aufgrund des Versagens des Wettbewerbs) und somit zu einer starken Leistungsverschlechterung führt. Der Kandidat hat nur zwei mögliche Werte: 0 bedeutet, dass es keinen Thread gibt, der bis zu 1 geweckt werden muss, um einen Nachfolge -Thread aufzuwachen, um um das Schloss zu konkurrieren.
Referenz: Sprechen Sie über synchronisierte Java -Parallelität
Wir wissen, dass synchronisiert ein Schwergewichtsschloss und seine Effizienz nicht sehr gut ist. Gleichzeitig war dieses Konzept immer in unserem Kopf. Die Implementierung von Synchronize wurde jedoch in JDK1.6 optimiert, wodurch es nicht so schwer ist. Welche Optimierungsmethoden verwendet der JVM?
Sperroptimierung
JDK1.6 führt viele Optimierungen für die Implementierung von Schlössern wie Spinschlösser, adaptive Spin -Schlösser, Sperreliminierung, Sperrroten, Vorspannungsschlösser, leichte Schlösser und andere Technologien ein, um den Overhead des Sperrbetriebs zu verringern.
Es gibt vier Hauptzustände von Schlössern, nämlich einen lockfreien Zustand, ein voreingenommener Schließstaat, einen leichten Schlosszustand und den Schwergewichtsstatus. Sie werden nach und nach mit dem heftigen Wettbewerb aufrüsten. Beachten Sie, dass Schlösser aktualisiert werden können und nicht herabgestuft werden können. Diese Strategie besteht darin, die Effizienz der Erlangung und Freisetzung von Schlösser zu verbessern.
Spin -Lock
Thread Blocking und Weck-up erfordert, dass die CPU von Benutzerstatus zu Kernstatus wechselt. Häufiges Blockieren und Aufwachen sind eine schwere Aufgabe für die CPU, und es wird unweigerlich viel Druck auf die gleichzeitige Leistung des Systems ausüben. Gleichzeitig stellten wir fest, dass in vielen Anwendungen der Schlosszustand der Objektschloss nur für einen sehr kurzen Zeitraum dauern wird. Es ist sehr unwürdig, den Thread für diesen kurzen Zeitraum häufig zu blockieren und aufzuwecken. Es wird also ein Spinschloss eingeführt.
Was ist Spin -Lock?
Das sogenannte Spin-Schloss besteht darin, den Faden einen Zeitraum zu warten und nicht sofort aufgehängt zu werden, um festzustellen, ob der Faden, der das Schloss hält, das Schloss schnell loslässt. Wie warte ich? Führen Sie einfach einen bedeutungslosen Zyklus (Spin) durch.
Das Warten von Spin kann das Blockieren nicht ersetzen. Lassen Sie uns über die Anforderungen für die Anzahl der Prozessoren sprechen (Multi-Core scheint, dass es jetzt keinen Single-Core-Prozessor gibt). Obwohl es den Overhead vermeiden kann, der durch Gewindeschaltung verursacht wird, nimmt es die Prozessorzeit in Anspruch. Wenn der Faden, der das Schloss hält, das Schloss schnell freigibt, ist die Spin -Effizienz sehr gut. Im Gegenteil, der Spin -Thread verbraucht die vergeblichen Verarbeitungsressourcen. Es wird keine sinnvolle Arbeit leisten. Es nimmt normalerweise die Grube ein und scheißt nicht, was stattdessen zu Leistungsabfällen führt. Daher muss die Zeit für das Warten von Spin (Anzahl der Drehungen) eine Grenze haben. Wenn der Spin die definierte Zeit überschreitet und das Schloss trotzdem nicht erhalten hat, sollte er suspendiert werden.
Spinlock wird in JDK1.4.2 eingeführt und standardmäßig ausgeschaltet, kann jedoch mit -xx:+usespinning eingeschaltet werden und wird standardmäßig in JDK1.6 eingeschaltet. Die Standardzahl der Spins gleichzeitig beträgt das 10 -fache, was durch Parameter -xx: Preblockspin eingestellt werden kann;
Wenn Sie die Spin -Anzahl der Spins des Spin -Sperre durch den Parameter -xx: Preblockspin einstellen, wird dies viele Unannehmlichkeiten verursachen. Wenn ich den Parameter auf 10 einstellte, aber viele Threads im System das Schloss freigeben, wenn Sie einfach beenden (wenn Sie sich ein- oder zweimal drehen, können Sie das Schloss erhalten), würden Sie sich verlegen? Daher führte JDK1.6 adaptive Spinschlösser ein und machte virtuelle Maschinen intelligenter und intelligenter.
Spin -Lock anpassen
JDK1.6 führt ein intelligenteres Spin -Lock vor, nämlich adaptive Spin -Lock. Die sogenannte Anpassung bedeutet, dass die Anzahl der Drehungen nicht mehr festgelegt ist, sie wird durch die Spin-Zeit auf demselben Schloss und den Zustand des Schlossbesitzers bestimmt. Wie macht ich das? Wenn sich der Thread erfolgreich dreht, wird die Anzahl der Drehungen das nächste Mal mehr sein, da die virtuelle Maschine der Ansicht ist, dass der Spin seit dem letzten Erfolg wahrscheinlich wieder erfolgreich ist und dass der Spin mehrmals warten kann. Im Gegenteil, wenn nur wenige Spins für ein bestimmtes Schloss erfolgreich sein können, wird die Anzahl der Drehungen reduziert oder sogar weggelassen, wenn das Schloss in Zukunft erforderlich ist, um keine Prozessorressourcen zu verschwenden.
Mit adaptiven Spin -Schlössern, da sich die Informationen zur Programmbetriebs- und Leistungsüberwachung weiter verbessern, wird die Vorhersage des Programms für den Programmsperrstatus durch die virtuelle Maschine immer genauer und virtuelle Maschinen werden schlauer.
Sperrausscheidung
Um die Integrität der Daten zu gewährleisten, müssen wir diesen Teil des Vorgangs bei der Durchführung von Operationen synchronisieren. In einigen Fällen erkennt die JVM jedoch, dass es keine Möglichkeit eines gemeinsamen Datenwettbewerbs gibt, weshalb der JVM diese Synchronisierungsschlösser sperrt. Die Grundlage für die Ausscheidung der Sperrausscheidung ist die Datenunterstützung für die Fluchtanalyse.
Wenn es keine Konkurrenz gibt, warum müssen Sie dann noch ein Schloss hinzufügen? Daher kann die Ausscheidung von Sperren Zeit sinnlos sparen und Schlösser anfordern. Ob die variablen Flucht für virtuelle Maschinen erforderlich ist, um festzustellen, ob Datenflussanalyse verwendet wird, ist sie den US -Programmierern jedoch immer noch unklar? Werden wir vor dem Codeblock eine Synchronisation hinzufügen, die eindeutig weiß, dass es keinen Datenwettbewerb gibt? Aber manchmal ist das Programm nicht das, was wir denken? Obwohl wir das Schloss nicht anzeigen, wenn wir einige JDK-integrierte APIs wie StringBuffer, Vector, Hashtable usw. verwenden, wird zu diesem Zeitpunkt eine unsichtbare Verriegelungsoperation vorhanden. Zum Beispiel die append () -Methode von StringBuffer und die Vektor -Methode add ():
public void vectortest () {vector <string> vector = new vector <string> (); für (int i = 0; i <10; i ++) {vector.add (i+""); } System.out.println (vector); }Beim Ausführen dieses Codes kann der JVM klar erkennen, dass der variable Vektor nicht der Methode vectortest () entkommt, sodass der JVM den Sperrvorgang im Vektor mutig eliminieren kann.
Sperraufrauung
Wir wissen, dass bei Verwendung einer Synchronisationsschloss der Umfang des Synchronisationsblocks so klein wie möglich sein muss - nur im tatsächlichen Umfang der gemeinsamen Daten synchronisiert. Der Zweck davon ist die Minimierung der Anzahl der Operationen, die so weit wie möglich synchronisiert werden müssen. Wenn es einen Schlosswettbewerb gibt, kann der Faden, der auf das Schloss wartet, auch so schnell wie möglich das Schloss erhalten.
In den meisten Fällen ist die obige Ansicht korrekt, und LZ hat sich immer an diese Ansicht haftet. Wenn jedoch eine Reihe kontinuierlicher Sperren und Entsperren zu unnötigen Leistungsverlusten führen kann, wird das Konzept der Verriegelung von Slutty eingeführt.
Das Konzept der Lock -Verleumdung ist leichter zu verstehen, nämlich die Verbindung mehrerer kontinuierlicher Verriegelung und Erschließung von Vorgängen zusammen und in ein Schloss mit einer größeren Reichweite ausdehnen. Wie im obigen Beispiel gezeigt: Der Vektor muss jedes Mal einen Sperrvorgang hinzufügen, wenn er hinzugefügt wird. Das JVM erkennt, dass dasselbe Objekt (Vektor) kontinuierlich gesperrt und entsperrt ist und eine größere Auswahl an verschlossenen und entsperrten Operationen zusammenfasst, dh der verschlossene und entsperrte Betrieb wird außerhalb der für die Loop bewegt.
Leichtes Schloss
Der Hauptzweck bei der Einführung leichter Schlösser besteht darin, den Leistungsverbrauch zu verringern, der durch die Verwendung von Betriebssystem -Mutexes unter der Prämisse mehrerer Wettbewerbe ohne mehrere Threads verursacht wird. Wenn die Abbi -Sperrfunktion ausgeschaltet ist oder mehrere Fäden um Vorspannungsschlösser konkurrieren, wird das Vorspannungsschloss auf ein leichtes Schloss verbessert, dann wird das leichte Schloss versucht, und die Schritte sind wie folgt:
Holen Sie sich das Schloss
Bestimmen Sie, ob sich das aktuelle Objekt in einem lock-freien Zustand befindet (Hashcode, 0, 01). In diesem Fall erstellt der JVM zunächst einen Speicherplatz namens Sperre -Datensatz im Stapelrahmen des aktuellen Threads, um die aktuelle Mark -Kopie des Sperrobjekts zu speichern (der Beamte fügt dieser Kopie ein vertriebenes Präfix hinzu, nämlich verdrängter Markwort). Andernfalls führen Sie Schritt (3) aus;
Der JVM verwendet den CAS -Vorgang, um das Mark -Wort des Objekts auf eine Korrektur zu aktualisieren, die auf Sperrenprotokoll zeigt. Wenn es erfolgreich angibt, dass das Schloss bestritten ist, wird das Schlossflag auf 00 geändert (was darauf hinweist, dass sich das Objekt in einem leichten Schließstatus befindet) und führt einen Synchronisationsoperation durch. Wenn es fehlschlägt, führen Sie Schritt (3) durch;
Bestimmen Sie, ob das Markwort des aktuellen Objekts auf den Stapelrahmen des aktuellen Threads zeigt. Wenn ja, bedeutet dies, dass der aktuelle Thread bereits die Sperre des aktuellen Objekts enthält und dann den synchronen Codeblock direkt ausführt. Andernfalls kann es nur bedeuten, dass das Schlossobjekt von anderen Threads beschlagnahmt wurde. Zu diesem Zeitpunkt muss das leichte Schloss in ein Schwergewichtsschloss erweitert werden, das Sperrflaggenbit wird zu 10 und der später wartende Faden wird in den Blockierungszustand eingebracht.
Lösen Sie das Schloss
Die Freisetzung von leichten Schlössern erfolgt ebenfalls durch CAS -Operationen. Die Hauptschritte sind wie folgt:
Entfernen Sie die in verdrängten Markierungen gespeicherten Daten in der Erwerbs -Leichtgewichtsschloss.
Ersetzen Sie die abgerufenen Daten in Mark -Word durch den CAS -Betrieb. Wenn es erfolgreich ist, bedeutet dies, dass das Schloss erfolgreich veröffentlicht wird, sonst wird es ausgeführt (3);
Wenn der Ersatz für CAS -Operationen fehlschlägt, bedeutet dies, dass andere Threads versuchen, das Schloss zu erwerben, und der suspendierte Faden muss während der Veröffentlichung des Schlosses geweckt werden.
Bei leichten Schlössern besteht die Grundlage für die Verbesserung der Leistung darin, dass "für die meisten Schlösser während des gesamten Lebenszyklus keinen Wettbewerb geben wird". Wenn diese Grundlage unterbrochen wird, gibt es zusätzlich zum gegenseitig ausschließenden Overhead zusätzliche CAS -Operationen. Daher sind leichte Schlösser im Fall von Multi-Thread-Wettbewerb langsamer als Schwergewichtsschlösser.
Die folgende Abbildung zeigt den Akquisitions- und Release -Prozess von leichten Schlössern
Positive Schloss
Der Hauptzweck bei der Einführung voreingenommener Schlösser besteht darin, unnötige leichte Sperrausführungspfade ohne Multi-Thread-Wettbewerb zu minimieren. In dem obigen erwähnte, dass der Sperren und Entsperren von leichten Schlössern erforderlich sind, um sich auf mehrere CAS-Atomanweisungen zu stützen. Wie verringert sich die Vorspannungsschloss unnötiger CAS -Operationen? Wir können die Struktur der Marke sehen. Sie müssen nur prüfen, ob es sich um eine vorgespannte Schloss handelt, die Sperre ist als ThreadID identifiziert. Der Verarbeitungsfluss ist wie folgt:
Holen Sie sich das Schloss
Erkennen Sie, ob sich Markwort in einem voreingenommenen Zustand befindet, dh, ob es sich um eine voreingenommene Sperre 1 handelt, und das Bit des Sperrausweiss ist 01;
Wenn es sich um einen voreingenommenen Zustand handelt, testen Sie, ob die Thread -ID die aktuelle Thread -ID ist. Wenn ja, führen Sie Schritt (5) aus, andernfalls führen Sie Schritt (3) aus;
Wenn die Thread -ID nicht die aktuelle Thread -ID ist, wird die Sperre durch den CAS -Betrieb konkurriert. Wenn der Wettbewerb erfolgreich ist, wird die Thread -ID von Mark -Wort durch die aktuelle Thread -ID ersetzt, andernfalls der Thread (4);
Das CAS-Wettbewerbsschloss scheitert, was beweist, dass derzeit eine Multi-Thread-Wettbewerbssituation besteht. Wenn der globale Sicherheitspunkt erreicht ist, wird der Gewinde, der das vorgespannte Schloss erhält, ausgesetzt, das vorgespannte Schloss wird auf ein leichtes Schloss verbessert und der am Sicherheitspunkt blockierte Thread führt weiterhin den synchronen Codeblock aus.
Führen Sie synchrone Codeblöcke aus
Veröffentlichung von Schlösser. Die Veröffentlichung des vorgespannten Schlosses nimmt einen Mechanismus an, bei dem nur der Wettbewerb das Schloss veröffentlichen kann. Der Thread veröffentlicht das voreingenommene Schloss nicht aktiv und muss darauf warten, dass andere Threads konkurrieren. Der Rückgänger von voreingenommenen Schlössern erfordert das Warten auf einen globalen Sicherheitspunkt (an diesem Punkt wird kein Code ausgeführt). Die Schritte sind wie folgt:
Machen Sie den Faden mit einem vorgespannten Schloss und bestimmen Sie, ob sich der Schlossobjektstein noch im verschlossenen Zustand befindet.
Schalten Sie die Verzerrung in Richtung SU und stellen Sie den lockfreien Zustand (01) oder den leichten Schlossstatus wieder her.
Die folgende Abbildung zeigt den Akquisitions- und Freigabeprozess von voreingenommenen Schlössern
Schwergewichtsschloss
Die Gewichtssperrung wird auch als Objektmonitor (Monitor) in JVM bezeichnet. Es ist Mutex in C sehr ähnlich. Zusätzlich zu Mutex (0 | 1), die sich gegenseitig ausschließt, ist es auch für die Implementierung der Funktion des Semaphors verantwortlich, dh mindestens eine Warteschlange von Wettbewerbsschlössern und eine Signalblockierungswarteschlange (Wartewarteschlange). Ersteres ist für den gegenseitigen Ausschluss verantwortlich, und letzteres wird für die Threadsynchronisation verwendet.
Schwergewichtsschlösser werden durch Monitore (Monitore) innerhalb von Objekten implementiert, wobei die Essenz von Monitoren darin besteht, sich auf die Implementierung des zugrunde liegenden Betriebssystems von Mutex zu verlassen. Das Umschalten zwischen den Tätern des Betriebssystems erfordert das Umschalten vom Benutzerzustand in den Kernelzustand, und die Schaltkosten sind sehr hoch.
Zusammenfassen
Das obige ist der gesamte Inhalt dieses Artikels über die detaillierte Erklärung des Implementierungsprinzips von Synchronized in Java. Ich hoffe, es wird für alle hilfreich sein. Wenn es Mängel gibt, hinterlassen Sie bitte eine Nachricht, um darauf hinzuweisen. Vielen Dank an Freunde für Ihre Unterstützung für diese Seite!