Der Artikel teilt 4 Beispiele für detaillierte Erläuterung von Synchronized
1. Ob synchronisierte Schlüsselwörter hinzugefügt werden sollen
public class threadTest {public static void main (String [] args) {Beispiel für Beispiel = neuer Beispiel (); Thread T1 = neuer Thread1 (Beispiel); Thread T2 = neuer Thread1 (Beispiel); t1.start (); t2.Start (); }} class Beispiel {public synchronisierte void excast () {für (int i = 0; i <5; ++ i) {try {thread.sleep (1000); } catch (interruptedException e) {e.printstacktrace (); } System.out.println ("excute:" + i); }}} Klasse Thread1 erweitert Thread {privates Beispiel; public thread1 (Beispiel Beispiel) {this.example = Beispiel; } @Override public void run () {example.excute (); }}Das Ausgabeergebnis des synchronisierten Schlüsselworts ist wie folgt
Zuerst wird ein Satz von 0-4 ausgegeben, und dann wird der nächste Satz ausgegeben, und die beiden Threads werden nacheinander ausgeführt.
Excut: 0
Excut: 1
EXCUTE: 2
Excut: 3
Excut: 4
Excut: 0
Excut: 1
EXCUTE: 2
Excut: 3
Excut: 4
Das Ausgabeergebnis des synchronisierten Schlüsselworts ist wie folgt
Zwei Threads führen die excute -Methode gleichzeitig und gleichzeitig aus
Excut: 0
Excut: 0
Excut: 1
Excut: 1
EXCUTE: 2
EXCUTE: 2
Excut: 3
Excut: 3
Excut: 4
Excut: 4
2. Multi-Threading-Situation mehrerer Methoden
public class threadTest {public static void main (String [] args) {Beispiel für Beispiel = neuer Beispiel (); Thread T1 = neuer Thread1 (Beispiel); Thread T2 = neuer Thread2 (Beispiel); t1.start (); t2.Start (); }} class Beispiel {public synchronisierte void excast () {für (int i = 0; i <5; ++ i) {try {thread.sleep (1000); } catch (interruptedException e) {e.printstacktrace (); } System.out.println ("excute:" + i); }} public synchronisierte void excast1 () {für (int i = 0; i <5; ++ i) {try {thread.sleep (1000); } catch (interruptedException e) {e.printstacktrace (); } System.out.println ("excute1:" + i); }}} Klasse Thread1 erweitert Thread {privates Beispiel; public thread1 (Beispiel Beispiel) {this.example = Beispiel; } @Override public void run () {example.excute (); }} Klasse Thread2 erweitert Thread {private Beispiel; public thread2 (Beispiel Beispiel) {this.example = Beispiel; } @Override public void run () {example.excute1 (); }}Die Ausführungsergebnisse sind wie folgt
Gleiches gilt für die Sequenz, und ein Thread wird ausgeführt, bevor ein anderer Thread ausgeführt wird.
Excut: 0
Excut: 1
EXCUTE: 2
Excut: 3
Excut: 4
Excute1: 0
Excute1: 1
Excute1: 2
Excute1: 3
exklusiv1: 4
Wenn das synchronisierte Schlüsselwort entfernt wird, werden die beiden Methoden gleichzeitig ausgeführt und haben keinen gegenseitigen Einfluss.
Aber wie in der Beispiel -Unterroutine auch zwei Methoden geschrieben:
Das Ausführungsergebnis ist immer die Ausgabe eines Threads und dann die Ausführung eines anderen Threads.
veranschaulichen:
Wenn ein Objekt mehrere synchronisierte Methoden hat und ein Thread zu einem bestimmten Zeitpunkt eine synchronisierte Methode eingegeben hat, können andere Threads nicht auf synchronisierte Methoden des Objekts zugreifen, bevor die Methode ausgeführt wird.
abschließend:
Wenn das synchronisierte Schlüsselwort eine Methode modifiziert, wird die Methode als Synchronisationsmethode bezeichnet.
Jedes Objekt in Java hat ein Schloss oder einen Monitor. Wenn ein Thread auf die synchronisierte Methode eines Objekts zugreift, ist das Objekt gesperrt und kein anderer Thread kann auf die synchronisierte Methode des Objekts zugreifen (hier bezieht sich auf alle Synchronisationsmethoden, nicht nur auf dieselbe Methode). Erst wenn der vorherige Thread die Ausführungsmethode abschließt (oder eine Ausnahme ausgelöst), wird die Sperre des Objekts freigegeben, sodass andere Threads erneut auf die synchronisierte Methode des Objekts zugreifen können.
Beachten Sie, dass das Objekt zu diesem Zeitpunkt gesperrt ist. Wenn es sich um ein anderes Objekt handelt, gibt es keine Restriktionsbeziehung zwischen den Objekten.
Beim Versuch, ein zweites Threadobjekt im Code zu konstruieren, wird ein neues Beispielobjekt übergeben, dann besteht keine Einschränkung zwischen der Ausführung der beiden Threads.
3. statische Synchronisationsmethode
Wenn eine synchronisierte Schlüsselwort-modifizierte Methode ebenfalls durch statische modifiziert wird, wurde zuvor gesagt, dass eine nicht statische Synchronisationsmethode das Objekt sperrte, aber die statische Methode gehört nicht zum Objekt, sondern zur Klasse und sperrt das Klassenobjekt der Klasse, in dem sich diese Methode befindet.
public class threadTest {public static void main (String [] args) {Beispiel für Beispiel = neuer Beispiel (); Beispiel 2 = new Beispiel (); Thread T1 = neuer Thread1 (Beispiel); Thread T2 = neuer Thread2 (Beispiel2); t1.start (); t2.Start (); }} class Beispiel {public synchronisierte statische void excast () {für (int i = 0; i <5; ++ i) {try {thread.sleep (1000); } catch (interruptedException e) {e.printstacktrace (); } System.out.println ("excute:" + i); }} public synchronisierte statische void excast1 () {für (int i = 0; i <5; ++ i) {try {thread.sleep (1000); } catch (interruptedException e) {e.printstacktrace (); } System.out.println ("excute1:" + i); }}} Klasse Thread1 erweitert Thread {privates Beispiel; public thread1 (Beispiel Beispiel) {this.example = Beispiel; } @Override public void run () {example.excute (); }} Klasse Thread2 erweitert Thread {private Beispiel; public thread2 (Beispiel Beispiel) {this.example = Beispiel; } @Override public void run () {example.excute1 (); }}Die Ausführungsergebnisse sind wie folgt
Excut: 0
Excut: 1
EXCUTE: 2
Excut: 3
Excut: 4
Excute1: 0
Excute1: 1
Excute1: 2
Excute1: 3
exklusiv1: 4
Wenn es keinen statischen Modifikator gibt und zwei Threads verschiedene Objekte übergeben, werden sie gleichzeitig gleichzeitig ausgeführt.
Wenn es sich also um eine statische Methode handelt (execute () und execute2 () haben beide statische Schlüsselwörter hinzugefügt), selbst wenn verschiedene Beispielobjekte an zwei Threads übergeben werden, werden die beiden Threads immer noch voneinander eingeschränkt. Man muss zuerst ausgeführt werden und dann der nächste.
abschließend:
Wenn eine synchronisierte Methode statisch ist und ein Thread auf die Methode zugreift, sperrt es nicht das Objekt, in dem sich die synchronisierte Methode befindet, sondern das Klassenobjekt, das der Klasse entspricht, in der sich die synchronisierte Methode befindet. In Java entsprechen diese Objekte, egal wie viele Objekte eine Klasse hat, einem einzigartigen Klassenobjekt. Wenn ein Thread auf zwei statische und synchronisierte Methoden von zwei Objekten derselben Klasse zugreift, ist seine Ausführungsreihenfolge auch sequentiell, dh ein Thread wird zuerst die Methode ausführen, und der andere Thread startet nach Abschluss der Ausführung.
4. Synchronisierter Block
synchronisiert (Objekt)
{
}
Dies bedeutet, dass der Thread das Objektobjekt sperrt, wenn es ausgeführt wird. (Beachten Sie, dass dieses Objekt ein Objekt jeder Klasse sein kann oder Sie dieses Schlüsselwort verwenden können.)
Auf diese Weise können Sie das gesperrte Objekt selbst angeben.
public class threadTest {public static void main (String [] args) {Beispiel für Beispiel = neuer Beispiel (); Thread T1 = neuer Thread1 (Beispiel); Thread T2 = neuer Thread2 (Beispiel); t1.start (); t2.Start (); }} class Beispiel {public void excast () {synchronized (this) {for (int i = 0; i <5; ++ i) {try {thread.sleep (1000); } catch (interruptedException e) {e.printstacktrace (); } System.out.println ("excute:" + i); }}} public void auspuff1 () {synchronized (this) {for (int i = 0; i <5; ++ i) {try {thread.sleep (1000); } catch (interruptedException e) {e.printstacktrace (); } System.out.println ("excute1:" + i); }}}}}} Klasse Thread1 erweitert Thread {private Beispiel; public thread1 (Beispiel Beispiel) {this.example = Beispiel; } @Override public void run () {example.excute (); }} Klasse Thread2 erweitert Thread {private Beispiel; public thread2 (Beispiel Beispiel) {this.example = Beispiel; } @Override public void run () {example.excute1 (); }}Die Ausführungsergebnisse sind wie folgt
Excut: 0
Excut: 1
EXCUTE: 2
Excut: 3
Excut: 4
Excute1: 0
Excute1: 1
Excute1: 2
Excute1: 3
exklusiv1: 4
Der Effekt, der mit dem Beispielprogramm 4 erzielt wird, entspricht dem von Beispielprogramm 2. Beide Threads werden eher nacheinander als gleichzeitig ausgeführt. Wenn ein Thread ausgeführt wird, ist das Objektobjekt gesperrt und der andere Thread kann den entsprechenden Block nicht ausführen.
Die synchronisierte Methode entspricht tatsächlich dem Umwickeln aller Anweisungen in der Methode mit einem synchronisierten Block und über das Bestehen dieses Schlüsselworts in den Klammern des synchronisierten Blocks. Wenn es sich um eine statische Methode handelt, muss das Klassenobjekt natürlich gesperrt werden.
Vielleicht beinhaltet nur wenige Codezeilen in einer Methode Thread -Synchronisationsprobleme, sodass der synchronisierte Block den Zugriff mehrerer Threads körniger als die synchronisierte Methode steuert. Nur auf den Inhalt im synchronisierten Block kann nicht gleichzeitig von mehreren Threads zugegriffen werden, und andere Anweisungen in der Methode können weiterhin gleichzeitig von mehreren Threads (einschließlich vor und nach dem synchronisierten Block) zugegriffen werden.
abschließend:
Die synchronisierte Methode ist eine grobkörnige gleichzeitige Kontrolle. Zu einem bestimmten Zeitpunkt kann nur ein Thread die synchronisierte Methode ausführen.
Der synchronisierte Block ist eine feinkörnige Parallelitätskontrolle, die den Code nur im Block synchronisiert. Andere Codes, die sich in der Methode befinden und außer synchronisierten Blöcken, können gleichzeitig von mehreren Threads zugegriffen werden.
In der obigen handelt es sich um die synchronisierte Blocksynchronisationsmethode der Java-Multi-Thread-Programmierung. Ich hoffe, es wird für das Lernen aller hilfreich sein.