1. Synchrones Problem aufgeworfen
Die Threadsynchronisation besteht darin, Schäden an Daten zu verhindern, wenn mehrere Threads auf ein Datenobjekt zugreifen.
Zum Beispiel: Sowohl Threads Threada als auch Faden betreiben dasselbe FOO -Objekt und ändern die Daten im FOO -Objekt.
Paket cn.thread; öffentliche Klasse foo {private int x = 100; public int getX () {return x; } public int fix (int y) {x = x - y; Rückkehr x; }} Paket cn.thread; öffentliche Klasse myrunnable implements runnable {private foo foo = new foo (); public static void main (String [] args) {Myrunnable run = new Myrunnable (); Thread ta = neuer Thread (Ausführen, "Thread-a"); Thread TB = neuer Thread (Ausführen, "Thread-B"); ta.start (); tb.start (); } public void run () {für (int i = 0; i <3; i ++) {this.fix (30); try {thread.sleep (1); } catch (interruptedException e) {e.printstacktrace (); } System.out.println (Thread.currentThread (). GetName () + ": Der x -Wert des aktuellen Foo -Objekts =" + foo.getX ()); }} public int fix (int y) {return foo.fix (y); }}Auslaufergebnisse:
Thread-B: Der x-Wert des aktuellen Foo-Objekts = 40
Thread-A: Der x-Wert des aktuellen Foo-Objekts = 40
Thread -B: Der x -Wert des aktuellen Foo -Objekts = -20
Thread -A: Der x -Wert des aktuellen Foo -Objekts = -20
Thread -B: Der x -Wert des aktuellen Foo -Objekts = -80
Thread -A: Der x -Wert des aktuellen Foo -Objekts = -80
Aus den Ergebnissen wurde festgestellt, dass ein solcher Ausgangswert offensichtlich unangemessen war. Der Grund dafür ist, dass zwei Threads auf Foo -Objekte ohne Kontrolle zugreifen und ihre Daten ändern.
Wenn Sie die Rationalität der Ergebnisse beibehalten möchten, müssen Sie nur ein Ziel erreichen, nämlich den Zugriff auf Foo einzuschränken, und nur ein Thread kann gleichzeitig darauf zugreifen. Dadurch wird die Rationalität der Daten im FOO -Objekt gewährleistet.
Im spezifischen Java -Code müssen zwei Vorgänge abgeschlossen werden:
Identifizieren Sie die FOO -Variable X der Ressourcenklasse, die vom Wettbewerb als privat besucht wird.
Synchronisieren Sie den Code, der die Variablen ändert, und verwenden Sie das synchronisierte Schlüsselwort, um die Methode oder den Code zu synchronisieren.
Paket cn.Thread; öffentliche Klasse Foo2 {private int x = 100; public int getX () {return x; } // Synchronisierte Methode öffentlich synchronisierte int fix (int y) {x = x - y; System.out.println ("Thread" + Thread.currentThread (). GetName () + "Ausführen endet" " + y +" ", der aktuelle Wert ist:" + x); Rückkehr x; } // // synchronisierter Codeblock // public int fix (int y) {// synchronisiert (this) {// x = x - y; // system.out.println ("thread" + thread.currentThread (). GetName () + "Run endet" " + y // ·". Paket cn.thread; public class myrunnable2 {public static void main (String [] args) {Myrunnable2 run = new Myrunnable2 (); Foo2 foo2 = neu foo2 (); Mythead t1 = run.new MyThread ("Thread a", foo2, 10); Mythead t2 = run.new MyThread ("Thread B", foo2, -2); Mythead t3 = run.new MyThread ("Thread C", foo2, -3); Mythead t4 = run.new MyThread ("Thread D", foo2, 5); t1.start (); t2.Start (); t3.Start (); t4.Start (); } class myThread erweitert Thread {private foo2 foo2; / ** aktueller Wert*/ privat int y = 0; MyThread (String -Name, foo2 foo2, int y) {super (name); this.foo2 = foo2; this.y = y; } public void run () {foo2.fix (y); }}} Faden Ein Lauf endet, reduziert "10", der aktuelle Wert ist: 90
Thread C läuft und endet, reduziert "-3", der aktuelle Wert ist: 93
Thread B läuft am Ende, reduziert sich "-2", der aktuelle Wert ist: 95
Thread D wird ausgeführt und endet, reduziert "5", der aktuelle Wert ist: 90
2. Synchronisation und Verriegelung
1. Das Prinzip der Schloss
Jedes Objekt in Java verfügt über ein integriertes Schloss.
Wenn das Programm auf einer nicht statischen synchronisierten Synchronisationsmethode ausgeführt wird, ist die Sperre, die der aktuellen Instanz der ausführenden Codeklasse (diese Instanz) zugeordnet ist. Ein Schloss, das ein Objekt erwirbt, wird auch als Erwerbsschloss bezeichnet, ein Objekt sperrt, ein Objekt sperrt oder ein Objekt synchronisiert.
Die Objektschloss funktioniert nur, wenn das Programm zu einer synchronisierten Synchronisationsmethode oder einem Codeblock ausgeführt wird.
Es gibt nur ein Schloss für ein Objekt. Wenn also ein Faden das Schloss erwirbt, kann kein anderer Faden das Schloss erwerben, bis der erste Faden das Schloss veröffentlicht (oder zurückgibt). Dies bedeutet auch, dass kein anderer Thread die synchronisierte Methode oder den Codeblock für das Objekt eingeben kann, bis die Sperre veröffentlicht wird.
Wenn Sie eine Sperre freigeben, verlässt der Sperr -Thread die synchronisierte Synchronisationsmethode oder den Codeblock.
Es gibt einige wichtige Punkte über das Verriegelung und die Synchronisation:
1) Nur Methoden können synchronisiert werden, aber Variablen und Klassen können nicht synchronisiert werden;
2) Jedes Objekt hat nur ein Schloss; Was sollte klar sein, wenn es um Synchronisation geht? Das heißt, welches Objekt synchronisiert ist?
3) Es ist nicht erforderlich, alle Methoden in der Klasse zu synchronisieren. Klassen können sowohl synchrone als auch asynchrone Methoden aufweisen.
4) Wenn zwei Threads die synchronisierte Methode in einer Klasse ausführen möchten und die beiden Threads dieselbe Instanz verwenden, um die Methode aufzurufen, kann die Methode jeweils nur ein Thread ausführen, und der andere muss warten, bis die Sperre veröffentlicht wird. Das heißt: Wenn ein Thread eine Sperre für ein Objekt erfasst, kann kein anderer Thread eine Synchronisationsmethode in der Klasse (dieses Objekts) eingeben.
5) Wenn der Faden Synchronisation und asynchrone Methoden aufweist, können die asynchronen Methoden von mehreren Fäden frei zugegriffen werden, ohne durch Schlösser eingeschränkt zu werden.
6) Wenn der Faden schläft, wird kein Schloss freigesetzt.
7) Threads können mehrere Schlösser erhalten. Wenn Sie beispielsweise die Synchronisationsmethode eines anderen Objekts in der Synchronisationsmethode eines Objekts aufrufen, erhalten die Synchronisationsschloss der beiden Objekte.
8) Die Synchronisation beeinträchtigt die Parallelität und sollte den Synchronisationsbereich so weit wie möglich einschränken. Die Synchronisation kann nicht nur die gesamte Methode synchronisieren, sondern auch einige Codeblöcke in der Methode synchronisieren.
9) Bei Verwendung von Synchronisationscodeblöcken sollten Sie angeben, welches Objekt synchronisiert werden soll, dh, welche Objektschloss erfasst werden soll. Zum Beispiel:
public int fix (int y) {synchronisiert (this) {x = x - y; } return x;} Natürlich kann die Synchronisationsmethode auch als asynchrone Methode neu geschrieben werden, aber die Funktionen sind beispielsweise genau gleich:
public synchronisierte int getX () {return x ++;} Und
public int getX () {synchronized (this) {return x ++; }}Der Effekt ist genau der gleiche.
3. Synchronisation der statischen Methode
Um statische Methoden zu synchronisieren, wird ein Schloss für das gesamte Klassenobjekt benötigt, das diese Klasse ist (xxx.class).
Zum Beispiel:
public static synchronisierte int setName (String -Name) {xxx.name = name;}
Äquivalent zu
public static int setName (String name) {synchronized (xxx.class) {xxx.name = name; }}4. Was passiert, wenn der Faden das Schloss nicht erhalten kann
Wenn der Thread versucht, eine synchrone Methode einzugeben und sein Schloss besetzt ist, wird der Faden auf dem Objekt blockiert. Im Wesentlichen tritt ein Thread in einen Pool des Objekts ein und muss warten, wo er warten muss, bis sein Schloss freigegeben wird und der Thread laufbar wird oder wieder ausgeführt wird.
Achten Sie beim Blockieren unbedingt darauf, welches Objekt zum Sperren verwendet wird:
1. Threads, die nicht statische Synchronisationsmethoden im selben Objekt aufrufen, blockieren sich gegenseitig. Wenn es sich um ein anderes Objekt handelt, hat jeder Thread seine eigene Objektschloss und Threads stören sich nicht gegenseitig.
2. Threads, die statische Synchronisationsmethoden in derselben Klasse aufrufen, blockieren sich gegenseitig und sind alle auf demselben Klassenobjekt gesperrt.
3.. Statische Synchronisationsmethoden und nicht statische Synchronisationsmethoden blockieren sich niemals gegenseitig, da statische Methoden auf Klassenobjekten gesperrt sind, während nicht statische Methoden auf Objekten dieser Klasse gesperrt sind.
4. Für synchronisierte Codeblöcke müssen Sie deutlich sehen, welche Objekte zum Sperren verwendet wurden (den Inhalt synchronisierter Klammern nach der Synchronisierung). Die auf demselben Objekt synchronisierten Themen blockieren sich gegenseitig und Threads, die auf verschiedenen Objekten gesperrt sind, blockieren sich niemals gegenseitig.
5. Wann ist die Synchronisation
Wenn mehrere Threads gleichzeitig auf gegenseitig ausschließliche (wechselbare) Daten zugreifen, sollte sie synchronisiert werden, um die Daten zu schützen, um sicherzustellen, dass beide Threads sie nicht gleichzeitig ändern und ändern.
Bei Daten, die in nicht statischen Feldern geändert werden können, werden normalerweise auf nicht statische Methoden zugegriffen.
Bei Daten, die in einem statischen Feld geändert werden können, wird normalerweise mit einer statischen Methode zugegriffen.
Das Problem wird sehr kompliziert, wenn Sie statische Felder in nicht statischen Methoden verwenden oder nicht statische Methoden in statischen Feldern aufrufen müssen. Es hat den Umfang der SJCP -Prüfung überschritten.
6. Thread -Sicherheitskategorie
Wenn eine Klasse gut synchronisiert ist, um ihre Daten zu schützen, wird diese Klasse "Thread-Safe" bezeichnet.
Selbst für Thread-Safe-Klassen sollten Sie sehr vorsichtig sein, da die Threads, die betrieben werden, immer noch nicht unbedingt sicher sind.
7. Zusammenfassung der Threadsynchronisation
1. Der Zweck der Threadsynchronisation besteht darin, den Schaden an Ressourcen zu schützen, wenn mehrere Threads auf eine Ressource zugreifen.
2. Die Thread -Synchronisationsmethode wird durch Schlösser implementiert. Jedes Objekt hat nur ein Schloss. Dieses Schloss ist einem bestimmten Objekt zugeordnet. Sobald der Thread die Objektsperrung erfasst hat, können andere Threads, die auf das Objekt zugreifen, nicht mehr auf andere Synchronisationsmethoden des Objekts zugreifen.
3. Für statische Synchronisationsmethoden sind Schlösser für diese Klasse und Sperrobjekte Klassenobjekte dieser Klasse. Die Schlösser statischer und nicht statischer Methoden stören sich nicht. Ein Faden erfasst eine Sperre und beim Zugriff auf eine Synchronisationsmethode auf einem anderen Objekt in einer Synchronisationsmethode erfasst er diese beiden Objektschlösser.
4. Für die Synchronisation ist es wichtig, immer bekannt zu sein, welches Objekt synchronisiert werden muss.
5. Beim Schreiben von Thread-Safe-Klassen müssen Sie immer darauf achten, korrekte Beurteilungen über die Logik und Sicherheit mehrerer Threads zu fällen, die mit dem Zugriff auf Ressourcen konkurrieren, die "Atomic" -Operationen analysieren und sicherstellen, dass andere Threads während des Atombetriebs nicht auf die konkurrierenden Ressourcen zugreifen können.
6. Wenn mehrere Threads auf eine Objektschloss warten, blockiert der Faden, der das Schloss nicht erhalten hat.
7. Deadlock wird durch Fäden verursacht, die aufeinander warten, und die Wahrscheinlichkeit des Auftretens in der Realität ist sehr klein. Wenn Sie wirklich ein Deadlock -Programm schreiben möchten, ist es möglicherweise nicht einfach zu bedienen, haha. Sobald ein Programm gestorben ist, wird das Programm jedoch sterben.
Original -Link: http://www.cnblogs.com/linjiqin/p/3208843.html
Das obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, es wird für das Lernen aller hilfreich sein und ich hoffe, jeder wird Wulin.com mehr unterstützen.