Der synchronisierte Java-Block wird verwendet, um Methoden oder Codeblöcke als synchronisiert zu markieren. Java-synchronisierte Blöcke werden verwendet, um Rennen zu vermeiden. In diesem Artikel wird der folgende Inhalt vorgestellt:
Java-Synchronisierungsschlüsselwort (synchronzied)
Instanzmethodensynchronisierung
Synchronisation statischer Methoden
Synchronisationsblöcke in Instanzmethoden
Synchronisationsblöcke in statischen Methoden
Beispiel für die Java-Synchronisierung
Synchronisierte Blöcke in Java sind mit „synchronisiert“ gekennzeichnet. Ein synchronisierter Block in Java wird auf ein bestimmtes Objekt synchronisiert. Alle auf einem Objekt synchronisierten synchronisierten Blöcke können nur von einem Thread gleichzeitig eingegeben und ausgeführt werden. Alle anderen Threads, die darauf warten, in diesen synchronisierten Block einzutreten, werden blockiert, bis der Thread, der diesen synchronisierten Block ausführt , ihn verlässt .
Es gibt vier verschiedene synchronisierte Blöcke:
Instanzmethoden
Statische Methoden
Synchronisierte Blöcke in Instanzmethoden
Synchronisierte Blöcke in statischen Methoden
Die oben genannten synchronisierten Blöcke werden alle auf verschiedenen Objekten synchronisiert. Welcher Synchronisationsblock tatsächlich benötigt wird, hängt von der Situation ab.
Das Folgende ist eine synchronisierte Instanzmethode:
public synchronized void add(int value){ this.count += value; }
Beachten Sie das synchronisierte Schlüsselwort in der Methodendeklaration. Dadurch wird Java mitgeteilt, dass die Methode synchron ist.
Die Synchronisierung der Java-Instanzmethode wird auf dem Objekt synchronisiert, das Eigentümer der Methode ist. Auf diese Weise wird die Methodensynchronisation jeder Instanz auf ein anderes Objekt synchronisiert, nämlich auf die Instanz, zu der die Methode gehört. Innerhalb eines synchronisierten Instanzmethodenblocks kann nur ein Thread ausgeführt werden. Wenn mehrere Instanzen vorhanden sind, kann ein Thread jeweils Operationen in einem instanzsynchronisierten Block ausführen. Ein Thread pro Instanz.
Die statische Methodensynchronisierung ist mit der Instanzmethodensynchronisierungsmethode identisch und verwendet außerdem das synchronisierte Schlüsselwort. Die Synchronisierung statischer Java-Methoden lautet wie folgt:
public static synchronized void add(int value){ count += value; }
In ähnlicher Weise teilt das synchronisierte Schlüsselwort hier Java mit, dass diese Methode synchronisiert ist.
Die Synchronisierung statischer Methoden bezieht sich auf die Synchronisierung des Klassenobjekts, in dem sich die Methode befindet. Da eine Klasse nur einem Klassenobjekt in der Java Virtual Machine entsprechen kann, darf nur ein Thread gleichzeitig statische Synchronisationsmethoden in derselben Klasse ausführen.
Für statisch synchronisierte Methoden in verschiedenen Klassen kann ein Thread die statisch synchronisierten Methoden in jeder Klasse ausführen, ohne zu warten. Unabhängig davon, welche statische synchronisierte Methode in der Klasse aufgerufen wird, kann eine Klasse nur von einem Thread gleichzeitig ausgeführt werden.
Manchmal muss nicht die gesamte Methode synchronisiert werden, sondern nur ein Teil davon. Java kann einen Teil einer Methode synchronisieren.
Ein Beispiel für einen synchronisierten Block in einer asynchronen Java-Methode ist wie folgt:
public void add(int value){ synchronized(this){ this.count += value; } }
Beispiel verwendet den Java-Konstruktor für synchronisierte Blöcke, um einen Codeblock als synchronisiert zu markieren. Dieser Code wird wie eine synchrone Methode ausgeführt.
Beachten Sie, dass der synchronisierte Java-Blockkonstruktor das Objekt in Klammern umgibt. Im obigen Beispiel wird „this“ verwendet, also die Instanz selbst, die die Add-Methode aufruft. Das im synchronisierten Konstruktor in Klammern eingeschlossene Objekt wird als Monitorobjekt bezeichnet. Der obige Code verwendet die Monitorobjektsynchronisierung, und die synchronisierte Instanzmethode verwendet die Instanz der aufrufenden Methode selbst als Monitorobjekt.
Innerhalb einer Java-Methode, die mit demselben Monitorobjekt synchronisiert ist, kann jeweils nur ein Thread ausgeführt werden.
Die folgenden beiden Beispiele synchronisieren die aufgerufenen Instanzobjekte, sodass sie hinsichtlich der Auswirkungen der Synchronisierungsausführung gleichwertig sind.
public class MyClass { public synchronized void log1(String msg1, String msg2){ log.writeln(msg1); log.writeln(msg2); } public void log2(String msg1, String msg2){ synchronized(this){ log.writeln(msg1); log.writeln(msg2); } } }
Im obigen Beispiel kann jeweils nur ein Thread in einer der beiden synchronisierten Blöcke gleichzeitig ausgeführt werden.
Wenn der zweite Synchronisationsblock nicht auf diesem Instanzobjekt synchronisiert ist, können die beiden Methoden gleichzeitig vom Thread ausgeführt werden.
Ähnlich wie oben finden Sie hier zwei Beispiele für die Synchronisierung statischer Methoden. Diese Methoden werden mit dem Klassenobjekt synchronisiert, zu dem die Methode gehört.
public class MyClass { public static synchronized void log1(String msg1, String msg2){ log.writeln(msg1); log.writeln(msg2); } public static void log2(String msg1, String msg2){ synchronized(MyClass.class){ log.writeln(msg1); log.writeln(msg2); } } }
Threads dürfen nicht gleichzeitig auf diese beiden Methoden zugreifen.
Wenn der zweite Synchronisationsblock nicht mit dem MyClass.class-Objekt synchronisiert ist. Dann können Threads gleichzeitig auf diese beiden Methoden zugreifen.
Im folgenden Beispiel werden zwei Threads gestartet, die beide die Add-Methode derselben Instanz der Counter-Klasse aufrufen. Da die Synchronisierung auf der Instanz erfolgt, zu der die Methode gehört, kann nur ein Thread gleichzeitig auf diese Methode zugreifen.
public class Counter{ long count = 0; public synchronized void add(long value){ this.count += value; } } public class CounterThread extends Thread{ protected Counter counter = null; public CounterThread(Counter counter){ this.counter = counter; } public void run() { for(int i=0; i<10; i++){ counter.add(i); } } } public class Example { public static void main(String[] args){ Counter counter = new Counter(); Thread threadA = new CounterThread(counter); Thread threadB = new CounterThread(counter); threadA.start(); threadB.start(); } }
创建了两个线程。他们的构造器引用同一个Counter实例。Counter.add方法是同步在实例上,是因为add方法是实例方法并且被标记上synchronized关键字。因此每次只允许一个线程调用该方法。另外一个线程必须要等到第一个线程退出add()方法时,才能继续执行方法。
如果两个线程引用了两个不同的Counter实例,那么他们可以同时调用add()方法。这些方法调用了不同的对象,因此这些方法也就同步在不同的对象上。这些方法调用将不会被阻塞。如下面这个例子所示:
public class Example { public static void main(String[] args){ Counter counterA = new Counter(); Counter counterB = new Counter(); Thread threadA = new CounterThread(counterA); Thread threadB = new CounterThread(counterB); threadA.start(); threadB.start(); } }
注意这两个线程,threadA和threadB,不再引用同一个counter实例。CounterA和counterB的add方法同步在他们所属的对象上。调用counterA的add方法将不会阻塞调用counterB的add方法。
Das obige ist der detaillierte Inhalt vonDetaillierte Einführung in die Verwendung von Java-synchronisierten Blöcken. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!