Die grundlegendste Synchronisationsmethode von Java besteht darin, das synchronisierte Schlüsselwort zu verwenden, um den gleichzeitigen Zugriff einer Methode zu steuern. Jede mit dem synchronisierte Schlüsselwort deklarierte Methode ist ein kritischer Abschnitt. In Java darf gleich eine der kritischen Abschnitte desselben Objekts gleichzeitig zugegriffen werden.
Statische Methoden haben unterschiedliche Verhaltensweisen. Auf eine statische Methode, die mit dem synchronisierten Schlüsselwort deklariert wird, kann nur von einem Ausführungs-Thread zugegriffen werden, aber andere Threads können auf die nicht statische synchronisierte Methode dieses Objekts zugreifen. Dies muss sehr vorsichtig sein, da zwei Threads gleichzeitig auf zwei verschiedene synchronisierte Methoden eines Objekts zugreifen können, d. H. Eine davon ist eine statische synchronisierte Methode und die andere ist eine nicht statische synchronisierte Methode. Wenn beide Methoden dieselben Daten ändern, tritt ein inkonsistenter Fehler auf.
Die Syntax des synchronisierten Blocks lautet wie folgt:
public void method () {synchronisiert (Ausdruck) {}} Es gibt zwei Verwendungen des synchronisierten Schlüsselworts. Einer wird nur in der Definition von Methoden verwendet, der andere ist der synchronisierte Block. Wir können nicht nur synchronisiert werden, um eine Objektvariable zu synchronisieren, sondern Sie können auch synchronisierte Synchronisierung statischer Methoden und nicht statischer Methoden in der Klasse verwenden.
Die erste: Synchronisation nicht statischer Methoden
Aus der von Java bezogenen Syntax können wir wissen, dass die Verwendung des synchronisierten Schlüsselworts zur Definition einer Methode die statischen Methoden und nicht statischen Methoden sperrt, die durch das Synchroniezd-Schlüsselwort in der Klasse definiert sind, ist jedoch etwas schwierig zu verstehen. Wenn Sie Blöcke synchronisiert möchten, um einen solchen Effekt zu erzielen, ist es nicht schwer zu verstehen, warum dieser Effekt erzeugt wird. Wenn Sie synchronisiert sind, um alle synchronisierten nicht-statischen Methoden in der Klasse zu sperren, müssen Sie dies nur als Parameter des synchronisierten Blocks verwenden, um in den synchronisierten Block zu gelangen. Der Code ist wie folgt:
public class test {public void method1 () {synchronisiert (this) {}} public synchronisierte void method2 () {}} public class test {public void method1 () {synchronisiert (this) {}} public synchronized void method2 () {{}}}}}} {{}} Im obigen Code verwendet Method1 den synchronisierten Block, und die Methode2 -Methode verwendet das synchronisierte Schlüsselwort, um die Methode zu definieren. Wenn Sie dieselbe Testinstanz verwenden, werden die anderen Methoden blockiert, da eine dieser beiden Methoden ausgeführt wird, da sie die Synchronisationsschloss nicht erhalten haben. Zusätzlich zur Verwendung dieses Parameters des synchronisierten Blocks können Sie auch Test verwenden. Dies als Parameter des synchronisierten Blocks, um denselben Effekt zu erzielen.
Bei der Verwendung synchronisierter Blöcke in inneren Klassen stellt dies nur innere Klassen dar und hat nichts mit äußeren Klassen (äußere Klasse) zu tun. Nichtstatische Methoden in inneren Klassen und nicht statischen Methoden in Außenklassen können jedoch auch synchronisiert werden. Wenn Sie der inneren Klasse eine Methodenmethode3 hinzufügen, können Sie auch mit den beiden Methoden im Test synchronisieren. Der Code lautet wie folgt:
public class test {class Innerclass {public void method3 () {synchronized (test.this) {}}} public class test {class Innerclass {public void method3 () {synchronized (test.this) {}}}}} Die Methode3 -Methode der Innerklasse oben und die Testmethoden für Methode1 und Methode2 können nur eine Methode gleichzeitig ausgeführt haben.
Unabhängig davon, ob der synchronisierte Block korrekt ausgeführt wird oder der synchronisierte Block aufgrund einer Ausnahme aufgrund eines Programmfehlers beendet ist, wird die vom aktuellen synchronisierte Block gehaltene Synchronisationsschloss automatisch veröffentlicht. Daher müssen Sie sich bei Verwendung des synchronisierten Blocks keine Sorgen um die Synchronisationsschloss machen.
2. Synchronisation statischer Methoden
Da Objektinstanzen beim Aufrufen statischer Methoden nicht unbedingt erstellt werden, kann dies nicht zur Synchronisierung statischer Methoden verwendet werden, sondern müssen Klassenobjekte verwenden, um statische Methoden zu synchronisieren. Der Code ist wie folgt:
public class test {public static void methode1 () {synchronized (test.class) {}} public static synchronisierte void method2 () {}} public class Test {public static void methode () {synchronised (test.clasWenn Sie statische Methoden synchronisieren, können Sie die statische Feldklasse der Klasse verwenden, um das Klassenobjekt zu erhalten. Im obigen Beispiel gibt es nur eine Methodenausführung von Methoden- und Methodenmethoden. Zusätzlich zur Verwendung des Klassenfeldes können Sie das Klassenobjekt über die GetClass () -Methode der Instanz erhalten. Der Code ist wie folgt:
public class test {public statischer Test; public test () {test = this; } public static void method1 () {synchronized (test.getClass ()) {}} public Class Test {public statischer Test; public test () {test = this; } public static void method1 () {synchronized (test.getClass ()) {}}}
Im obigen Code erhalten wir eine Instanz des Tests über ein öffentliches statisches Objekt und erhalten ein Klassenobjekt über die GetClass -Methode dieser Instanz (beachten Sie, dass alle Instanzen einer Klasse über die GetClass -Methode erhalten werden). Wir können auch statische Methoden verschiedener Klassen durch die Klasse synchronisieren. Der Code lautet wie folgt:
public class test1 {public static void method1 () {synchronized (test.class) {}}} public class test1 {public static void methode1 () {synchronized (test.class) {}}}}
Hinweis: Wenn synchronisierte Blöcke zum Synchronisieren von Methoden verwendet werden, können nicht statische Methoden synchronisiert werden, während statische Methoden mit Klassenobjekten synchronisiert werden müssen. Nichtstatische Methoden können jedoch auch mithilfe der Klasse synchronisiert werden. Dies kann jedoch nicht in statischen Methoden verwendet werden, um nicht statische Methoden zu synchronisieren. Dies muss bei der Verwendung synchronisierter Blöcke geachtet werden.
Notiz
Das synchronisierte Schlüsselwort verschlechtert die Leistung der Anwendung und kann daher nur bei Methoden verwendet werden, bei denen gemeinsame Daten in gleichzeitigen Szenarien geändert werden müssen. Wenn mehrere Threads auf die gleiche synchronisierte Methode zugreifen, kann nur ein Thread darauf zugreifen und die anderen Threads warten. Wenn die Methodeerklärung das synchronisierte Schlüsselwort nicht verwendet, können alle Threads die Methode gleichzeitig ausführen, wodurch die Gesamtlaufzeit verkürzt wird. Wenn Sie bekannt sind, dass Sie von mehr als einem Thread aufgerufen werden, müssen Sie es nicht mit dem synchronisierten Schlüsselwort deklarieren.
Synchronisierte Methoden können rekursiv bezeichnet werden. Wenn ein Thread auf die Synchronisationsmethode eines Objekts zugreift, kann er auch andere Synchronisierungsmethoden des Objekts, einschließlich der ausführenden Methode, aufrufen, ohne dass er erneut Zugriff auf die Methode erhalten muss.
Wir können den Zugriff auf Codeblöcke (anstelle der gesamten Methode) über das synchronisierte Schlüsselwort schützen. Das synchronisierte Schlüsselwort sollte wie folgt verwendet werden: Der Rest der Methode bleibt außerhalb des synchronisierten Codeblocks, um eine bessere Leistung zu erzielen. Der Zugriff auf den kritischen Abschnitt (d. H. Codeblöcke, auf die nur von einem Thread gleichzeitig zugegriffen werden kann) sollten so kurz wie möglich sein. Zum Beispiel verwenden wir beim Erhalten der Anzahl der Personen in einem Gebäude nur das synchronisierte Schlüsselwort, um die Anweisungen zur Aktualisierung der Anzahl der Personen zu schützen und andere Vorgänge nicht mit gemeinsam genutzten Daten zu verwenden. Bei der Verwendung von synchronisierten Schlüsselwörtern auf diese Weise muss die Objektreferenz als eingehender Parameter verwendet werden. Nur ein Thread darf gleichzeitig auf diesen synchronisierten Code zugreifen. Im Allgemeinen verwenden wir dieses Schlüsselwort, um auf das Objekt zu verweisen, zu dem die ausführende Methode gehört:
synchronisiert (this) {// Java -Code}