Die Auswirkung der Synchronisierung auf den Code bei Verwendung an verschiedenen Stellen:
1. Synchronisierte Schlüsselwortänderungsmethode
Angenommen, P1 und P2 sind unterschiedliche Objekte derselben Klasse. Diese Klasse definiert die Synchronisierung in den folgenden Situationen oder synchronisierte Methode, P1 und P2 können sie aufrufen.
public synchronisiert void method(){
//
}
Dies ist die synchronisierte Methode, und was synchronisiert sperrt, ist zu diesem Zeitpunkt der Aufruf dieses synchronisierten Methodenobjekts. Mit anderen Worten: Wenn ein Objekt P1 diese Synchronisationsmethode in verschiedenen Threads ausführt, schließen sie sich gegenseitig aus, um einen Synchronisationseffekt zu erzielen. Wenn gleichzeitig mehrere synchronisierte Methoden im Objekt vorhanden sind und ein Thread eine synchronisierte Methode im Objekt ausführt, dürfen andere synchronisierte Methoden im Objekt nicht von anderen Threads ausgeführt werden. Allerdings kann ein anderes Objekt P2, das von der Klasse generiert wird, zu der dieses Objekt gehört, diese Methode mit dem hinzugefügten synchronisierten Schlüsselwort willkürlich aufrufen.
Der obige Beispielcode entspricht dem folgenden Code:
public void method() {
synchronisiert (this) Diesmal handelt es sich um eine Objektsperre des P1-Objekts. Nur der Thread erhält das P1-Objekt Die Sperre kann die Synchronisationsmethode von P1 aufrufen. In dieser Situation kann die P1-Sperre auch die Kontrolle über den Synchronisationsmechanismus verlieren.
2. Synchronisierter Block, der Beispielcode lautet wie folgt:
public void method(SomeObject so) {
synchronisiert(so)
{
//..
}
}
Zu diesem Zeitpunkt ist die Sperre das So-Objekt, und jedes Objekt entspricht einer eindeutigen Sperre, sodass jeder Thread, der die Objektsperre erhält, den von ihm gesteuerten Code ausführen kann. Wenn ein klares Objekt als Sperre vorhanden ist, können Sie das Programm wie folgt schreiben. Wenn jedoch kein klares Objekt als Sperre vorhanden ist und Sie nur einen Codeabschnitt synchronisieren möchten, können Sie eine spezielle Instanzvariable erstellen (dies muss der Fall sein). ein Objekt), das als Sperre fungiert:
private byte[] lock = new byte[0];
Public void method(){
synchronisiert(lock)
{
}
PS: Ein Byte-Array-Objekt mit der Länge Null ist wirtschaftlicher zu erstellen als jedes andere Objekt – schauen Sie sich den kompilierten Bytecode an: Für die Generierung eines Byte[]-Objekts mit der Länge Null sind nur 3 Opcodes und eine Objektsperre erforderlich = new Object() erfordert 7 Zeilen Opcode.
3. Synchronisiert auf statische Funktionen anwenden. Der Beispielcode lautet wie folgt: public void method2()
{
synchronisiert(Foo.class)
//
}
}
Beide davon Zwei synchronisierte Methoden rufen die Klasse auf, zu der das Objekt dieser Methode gehört (Klasse, und nicht ein bestimmtes, von dieser Klasse generiertes Objekt).
Es kann gefolgert werden: Wenn eine synchronisierte statische Funktion A in einer Klasse definiert ist und auch eine synchronisierte Instanzfunktion B definiert ist, dann, wenn dasselbe Objekt Obj dieser Klasse in mehreren Threads auf die Methoden A bzw. B zugreift, Es findet keine Synchronisierung statt, da ihre Sperren unterschiedlich sind. Die Sperre von Methode A ist die Klasse, zu der Obj gehört, und die Sperre von Methode B ist das Objekt, zu dem Obj gehört.