In der Java-Dokumentation heißt es:
Es ist nicht möglich, dass zwei Aufrufe synchronisierter Methoden für dasselbe Objekt verschachtelt werden.
Was bedeutet das für eine statische Methode? Da eine statische Methode keinem Objekt zugeordnet ist, wird das synchronisierte Schlüsselwort die Klasse anstelle des Objekts sperren?
this
ist die Sperre für Instanzmethoden erworben -, bitte beheben Sie sie Oscar.Um der Antwort von Oscar (erfreulich prägnant!) Ein kleines Detail hinzuzufügen, lautet der relevante Abschnitt in der Java-Sprachspezifikation 8.4.3.6, 'Synchronisierte Methoden' :
quelle
Ein Punkt, bei dem Sie vorsichtig sein müssen (mehrere Programmierer fallen im Allgemeinen in diese Falle), ist, dass es keine Verbindung zwischen synchronisierten statischen Methoden und synchronisierten nicht statischen Methoden gibt, dh:
Main:
Thread 1:
Thread 2:
f () und g () sind nicht miteinander synchronisiert und können daher vollständig gleichzeitig ausgeführt werden.
quelle
synchronized (MyClass.class) {...}
.Es sei denn, Sie implementieren g () wie folgt:
Ich finde dieses Muster auch nützlich, wenn ich den gegenseitigen Ausschluss zwischen verschiedenen Instanzen des Objekts implementieren möchte (was beispielsweise beim Zugriff auf eine externe Ressource erforderlich ist).
quelle
getClass()
der Laufzeittyp zurückgegeben wird . Wenn Sie die Klasse unterordnen, werden die übergeordnete Klasse und die untergeordnete Klasse auf verschiedenen Sperren synchronisiert.synchronized(MyClass.class)
Dies ist der richtige Weg, wenn Sie sicherstellen möchten, dass alle Instanzen dieselbe Sperre verwenden.Schauen Sie sich die Oracle-Dokumentationsseite zu Intrinsic Locks and Synchronization an
quelle
Einer statischen Methode ist auch ein Objekt zugeordnet. Es gehört zur Class.class-Datei im JDK-Toolkit. Wenn die .class-Datei in den RAM geladen wird, erstellt die Class.class eine Instanz davon, die als Vorlagenobjekt bezeichnet wird.
Beispiel: - Wenn Sie versuchen, ein Objekt aus einer vorhandenen Kundenklasse wie zu erstellen
Die Customer.class wird in den RAM geladen. In diesem Moment erstellt Class.class im JDK-Toolkit ein Objekt namens Template-Objekt und lädt diese Customer.class in dieses Template-Objekt. Statische Mitglieder dieser Customer.class werden zu Attributen und Methoden in diesem Template-Objekt.
Eine statische Methode oder ein statisches Attribut hat also auch ein Objekt
quelle
Die folgenden Beispiele geben mehr Klarheit zwischen Klassen- und Objektsperre. Ich hoffe, das folgende Beispiel hilft auch anderen :)
Zum Beispiel haben wir folgende Methoden: eine Erfassungsklasse und eine andere Erfassungsobjektsperre:
Jetzt können wir also folgende Szenarien haben:
Wenn Threads, die dasselbe Objekt verwenden, gleichzeitig versuchen, auf die
objLock
OR-staticLock
Methode zuzugreifen (dh beide Threads versuchen, auf dieselbe Methode zuzugreifen)Wenn Threads, die dasselbe Objekt verwenden, gleichzeitig versuchen, auf Methoden
staticLock
undobjLock
Methoden zuzugreifen (versucht, auf verschiedene Methoden zuzugreifen)Wenn Threads, die ein anderes Objekt verwenden, versuchen, auf die
staticLock
Methode zuzugreifenWenn Threads, die ein anderes Objekt verwenden, versuchen, auf die
objLock
Methode zuzugreifenquelle
Für diejenigen, die nicht mit der statischen synchronisierten Methode vertraut sind, die für das Klassenobjekt gesperrt ist, z. B. für die Zeichenfolgenklasse, wird die String.class gesperrt, während die instanzsynchronisierte Methode die aktuelle Instanz des Objekts sperrt, die in Java mit dem Schlüsselwort "this" gekennzeichnet ist. Da beide Objekte unterschiedlich sind, haben sie unterschiedliche Sperren. Während ein Thread eine statisch synchronisierte Methode ausführt, muss ein anderer Thread in Java nicht auf die Rückkehr dieses Threads warten, sondern erhält eine separate Sperre, die als Byte .class-Literal bezeichnet wird, und tritt ein statisch synchronisierte Methode.
quelle