Synchronisierte Nutzung und einfache analytische

Synchronisierte Nutzung und einfache analytische

1. Nutzungsszenarien:

Wenn gleichzeitig mehrere Threads auf denselben kritischen Ressourcen arbeiten, werden wir feststellen, dass der Code nicht synchronisiert ist, in den Ergebnissen resultierenden unsere Erwartungen übertroffen werden können. Zum Beispiel das folgende Beispiel:


public class Async implements Runnable {
	
	//临界变量
	static int i=0;
	
 public static void increase()
	{
		for(int i=0;i<5;i++)
		{
			System.out.print(i);
		}
	}
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		
		increase();
	}
	
	public static void main(String[] args) throws InterruptedException {
		// TODO Auto-generated method stub
		
		Async async = new Async();
		Async async2 = new Async();
		
		Thread thread1 = new Thread(async);
		Thread thread2 = new Thread(async2);
		
	
		thread1.start();
		thread2.start();
		thread1.join();
		thread2.join();
		//join 表示将当前线程执行完毕后再返回线程
	}
/*
每次运行的结果是随机的
*/

}

wir finden können diesen Code laufen zu lassen ist nicht das gleiche Ergebnis jedes Mal , wenn die Ausführung von Code. Dies ist das Ergebnis Fäden nicht synchronisiert sind. Und wenn wir den Code Synchronisation werden wollen, müssen Sie Sperre.
Die gesperrten Modus ist sehr einfach, fügen Sie ein Schlagwort auf dem Vormarsch () Methode: die synchronisiert sein kann.
Wie folgt:

synchronized public static void increase()
	{
		for(int i=0;i<5;i++)
		{
			System.out.print(i);
		}
	}

2. Einstufung

Die nächste wird synchronisiert Fall wird in zwei Kategorien unterteilt. Eine davon ist die Objektsperre, sperren und Klasse.
Objekt sperren Sie die Sperrobjekt, Java - Objekt - Header - Informationen Mark Word - Feld speichert Informationen über das Schloss.

3. Spezifische Anwendungen:

synchronisiert Es gibt drei Hauptanwendungen:

  • Beispiele für modifizierte Verfahren angewendet der Strom auf das Verriegelungs Beispiel vor einem Synchronisationscode Eingabe der aktuellen Instanz des Schlosses zu erhalten,

  • Modifikation von statischen Methoden, die Rolle der aktuellen Klasse Objektverriegelung, bevor die Sperre Synchronisationscode Eingabe der aktuellen Klassenobjekt zu erhalten

  • Modifizieren des Codeblock bezeichneten Sperrobjekt, ein bestimmtes Objekt zu sperren, bevor das Synchronisationscodebibliothek Eingabe einer gegebenen Verriegelung des Objekts zu erhalten.

Beispiele 3.1 Verfahren angewendet:


public class Async implements Runnable {
	
	//临界变量
	static int n=0;
	
	 public synchronized  void increase()
	{
		for(int i=0;i<5;i++)
		{
			n++;
			System.out.print(n);
		}
	}
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		
		increase();
	}
	

	public static void main(String[] args) throws InterruptedException {
		// TODO Auto-generated method stub
		
		Async async = new Async();
		
		Thread thread1 = new Thread(async );
		Thread thread2 = new Thread(async );
		
	
		thread1.start();
		thread2.start();
		thread1.join();
		thread2.join();

	}

	

}

3.2 Modifizierte statische Methode:

Wenn mehrere Objekte in unserem Code für den Zugriff der gleichen statischen Ressourcen sind, müssen wir die statischen Ressourcen sperren.


public class Async implements Runnable {
	
	//临界变量
	static int n=0;
	
	 public synchronized static void increase()
	{
		for(int i=0;i<5;i++)
		{
			n++;
			System.out.print(n);
		}
	}
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		
		increase();
	}
	

	public static void main(String[] args) throws InterruptedException {
		// TODO Auto-generated method stub
		
		Async async = new Async();
		Async async2 = new Async();
		
		Thread thread1 = new Thread(async );
		Thread thread2 = new Thread(async2 );
		
	
		thread1.start();
		thread2.start();
		thread1.join();
		thread2.join();

	}

	

}

3.3 Festlegen eines modifizierten Codeblöcke:

Wenn unsere Methode zu groß ist, aber der Code-Block Notwendigkeit, nur einen kleinen Teil der Zeit synchronisiert werden, wollen wir nur Synchronisierungssperre auf dem synchronisierten Codeblock hinzuzufügen, wie folgt:


public class Async implements Runnable {
	
	private static Async async = new Async();
	
	//临界变量
	static int n=0;
	

	@Override
	public void run() {
		// TODO Auto-generated method stub
		
		synchronized(this)//this指代async 对象
		{
			for(int i=0;i<5;i++)
			{
				n++;
				System.out.print(n);
			}
		}
	}
	

	public static void main(String[] args) throws InterruptedException {
		// TODO Auto-generated method stub
		
		
		Thread thread1 = new Thread(async);
		Thread thread2 = new Thread(async);
		
	
		thread1.start();
		thread2.start();
		thread1.join();
		thread2.join();

	}

	

}

Wenn das Blocksynchronisierungssperre verwenden, können wir das Objekt, das Sie synchronisieren möchten passieren, oder Klassenobjekt.

Es ist erwähnenswert, dass, wenn das nicht-statische Synchronsperre, Thread B die nicht-statische Synchronverriegelung, wenn ein Thread eines Anruf, der eine Objektsperre Anruf, ein Anruf an Klassensperre aufruft, wenn die beiden Sperren sich nicht gegenseitig ausschließen. Zu diesem Zeitpunkt wird es fadenSicherheitsFragen erzeugen.

4. einfache analytische

4.1Monitor

In dem JVM, Objekt - Layout im Speicher ist in drei Bereiche unterteilt: die ersten Objekte, beispielsweise Daten, und die Ausrichtung padding.
Im Objekt - Header gibt es ein Feld namens Markdown ist dieses Feld mit variabler Länge. Welche Geschäfte hashCode Objektsperre Informationen oder das Alter oder die Generationen GC Zeichen und andere Informationen. Schwergewicht Schlösser , gespeichert in den Informationspunkten auf einen Monitor Objekt (Monitor Objekt). Java jedes Objekt ein entsprechendes Überwachungsobjekt. Wenn der Monitor durch einen Faden gehalten wird, wird das Objekt in einem verriegelten Zustand sein.

Java Virtual Machine (HotSpot) in, ObjectMonitor-Monitor implementiert ist, ist die Hauptdatenstruktur wie folgt (in den HotSpot VM ObjectMonitor.hpp Quelldateien, C ++ Implementierung)

ObjectMonitor gibt es zwei Warteschlangen, und _WaitSet _EntryList, ObjectWaiter Objektliste zu speichern (jeder Thread die Sperre warten zu verpackenden Objekte ObjectWaiter), _ Besitzer Gewinde hält ObjectMonitor Objektpunkt, wenn eine Vielzahl von Fäden gleichzeitig die Synchronisationsperiode zugreifen wenn der Code, gibt _EntryList ersten Satz, wenn der Faden das Überwachungsobjekt eintritt Bereich _Owner Monitor erworben und der Besitzer ist der aktuelle Thread, während die variablen eingestellt werden, um die Zählung des Zählers zu überwachen, um 1, wenn der anrufende Faden wait () Methode inkrementiert, die Freigabe zur Zeit gehalten Monitor, Inhaber variable Erholung null ist, zählt von minus 1, während der Faden WaitSe t eingestellte Warte betritt geweckt zu werden. Wenn der aktuelle Thread ist, wird loslassen beendet den Monitor (lock) und setzt den Wert der Variablen, so dass andere Threads in den Monitor holen (lock). Wie in Fig.

Hier hat Bild einfügen Beschreibung

4.2 Methode Lock:

Das Verfahren zur impliziten Synchronisationsstufe, das heißt, ohne durch die Bytecode-Befehle gesteuert es den Methodenaufruf und Rückführung in dem Betrieb implementiert. JVM, wenn eine Methode aus dem Synchronisationsverfahren des Verfahrens der Konstanten-Pool-Tabelle Struktur ACC_SYNCHRONIZED Zugriffsmethode Flags (method_info Struktur) zu unterscheiden. Wenn das Verfahren aufgerufen wird, wird der Aufruf-Instruktion prüfen, ob das Verfahren der ACC_SYNCHRONIZED Zugriffs-Flag gesetzt ist, wenn gesetzt, wird Ausführungs-Thread ersten Haltemonitor (der Begriff Virtual Machine Specification verwendet, ist das Rohr), dann wird das Verfahren durchzuführen, und schließlich Eine andere Weise (sowohl normale als auch nicht normale Beendigung bzw. Fertigstellung) Zeitfreigabemonitor zu bewerkstelligen. Während des Verfahrens der Ausführung hält Ausführungs-Thread den Monitor, kann kein anderer Thread nicht länger erhalten demselben Monitor. Wenn ein Synchronisationsverfahren löst eine Ausnahme während der Ausführung und kann diese Ausnahme in der Art und Weise nicht damit umgehen, dass diese Synchronisationsverfahren durch den Monitor gehalten wird automatisch freigegeben, wenn eine Ausnahme außerhalb des Synchronisationsverfahren geworfen.

5.Java Optimierung der virtuellen Maschine synchronisiert

Es gibt vier Zustand des Schlosses, keine Sperrstatus, neigen zu sperren, leichte und schwere Verriegelungsschloss. Mit dem Schloss des Wettbewerbs können Sie von Schloss zu Schloss Upgrade leichte Sperre voreingenommen, dann Schwergewicht Sperre aktualisieren, aber die Sperre Eskalation ist unidirektional, die nur von niedrig bis hoch Upgrade zu sagen ist, wird die Sperre nicht angezeigt degradieren.

5.1 vorgespannte Verriegelungs

Vorbelastet den Hauptreferenzszenario Verriegelung wird: In einigen Fällen kann eine Sperre die meiste Zeit werden mehrere Threads nicht gleichzeitig konkurrieren, aber von demselben Thread wiederholt entschieden häufig worden. Vorgespannte Verriegelungskernidee ist, dass, wenn ein Thread die Sperre erhält, dann wird die Verriegelungs Bias-Modus zu gelangen, in der Mark Wortstruktur wird ebenfalls Verriegelungsstruktur vorgespannt ist, wenn der Faden wieder eine Sperre anfordert, und keine weitere Synchronisation, nämlich der Prozess die Sperre zu erwerben, so dass eine große Anzahl von Operationen eliminiert die Anwendung von Schlössern eingingen, die die Leistung des Programms liefern. Aber wenn eine Ressource oft mehrere Threads vorbelegt, wenn voreingenommen nicht für Sie sperren. Nach dem Ausfall voreingenommen Sperren und wird nicht sofort Schwergewicht Sperre erweitern, aber die erste leichte Sperre aktualisieren.

5.2 Leichtes Schloss

Wenn neigen Sperre fehlschlägt, wird die virtuelle Maschine nicht sofort auf Schwergewichts-Sperre aktualisieren, wird es versuchen, die Verwendung eines Werkzeugs ein leichtes Schloss (nach Zugabe von 1.6), dann Mark Wortstruktur auch Licht genannt zu optimieren wird die Reihenfolge der Verriegelungsstruktur. Basierend auf einem leichten Schloss, um die Leistung des Programms zu verbessern ist es, „die meisten Schleusen, gibt es keinen Wettbewerb in der gesamten Synchronisationszyklus“ Beachten Sie, dass diese empirische Daten. Notwendigkeit zu verstehen, dass die leichte Sperre die Anpassung der Szene abwechselnd Thread Gelegenheit Sync-Block durchgeführt wird, wenn es eine Sperre für den Zugriff ist die gleiche Gelegenheit zur gleichen Zeit, wird es auf die leichte Schwergewichts-Verriegelung Inflation führen.

5.3 Spinlocks

Nach einer leichte Sperre ausfällt,. Die virtuelle Maschine, um den wirklichen Faden hängt in der Betriebssystemebene, sondern auch ein Mittel zur Optimierung bekannt als Spin-Lock zu vermeiden Dieser Zustand ist die Notwendigkeit, die Konvertierung benutzerbasierte, in den meisten Fällen der Faden, der die Sperrzeit hält nicht zu lang sein, wenn sie direkt gesperrtes Betriebssystemebene Gewinde sind verschwendet werden kann, nachdem alle, das Betriebssystem, um zwischen Threads Kernzustandsübergänge zwischen dem Zustand erfordert einen relativ langen Zeitraum, ist die Zeit, Kosten relativ hoch, so dass der Spin-Lock-in naher Zukunft übernehmen wird, kann der aktuelle Thread die Sperre erwerben, so dass die Möglichkeiten für virtuelle Threads, die derzeit wollen, eine Sperre erhalten tut ein paar leeren Zyklus (das auch als Gründe Spin bekannt ist), in der Regel nicht zu lang ist, kann es 50 Zyklen oder 100 Zyklen sein, nach mehreren Zyklen, wenn Sie eine Sperre erhalten, sie erfolgreich den kritischen Bereich betreten. Wenn Sie nicht die Sperre bekommen, wird es die Betriebssystemebene Faden hängt sein, das ist die Art und Weise zu optimieren Spin-Lock, in der Tat, auf diese Weise kann die Effizienz verbessern. Schließlich kann keine Möglichkeit, es nur gesperrt Schwergewicht aufgerüstet werden.

5.4 Sperren Beseitigung

Die Beseitigung der Sperre wird eine andere virtuelle Maschine Lock-Optimierung, diese Optimierung gründlichere ist, Java Virtual Machine JIT Kompilierung (kann verstanden werden als ein einfaches Stück Code kompiliert werden, wenn etwa zum ersten Mal ausgeführt wird, auch bekannt als Echtzeit-Kompilierung), durch Abtasten Betrieb des Schlosses Zusammenhang kann es keine Entfernung der Ressource Wettbewerb geteilt, wodurch auf diese Weise die Sperre nicht erforderlich ist, kann es an der Zeit Verriegelungsanforderungen bedeutungslos, wie die String append ein Synchronisationsverfahren, aber fügen sie in der Art und Weise speichern das Stringbuffer gehört in einer lokalen Variable, und wird nicht von anderen Threads verwendet werden, so kann es kein Stringbuffer Szene gemeinsam genutzte Ressource Anstoß sein, wird automatisch eliminiert JVM arretieren.

6.synchronized wichtigsten Punkte:

6.1

synchronisiert ist einspringenden, was bedeutet, wenn ein Thread die Sperre hält, wieder, wenn gewünscht, nicht blockiert werden.

6.2

Wenn ein Thread Interrupts, Interrupt-Methode Thread-Instanz eines Objekts ruft die abnorme Unterbrechung blockiert und wirft InterruptedException Ausnahmen, wird auch der Unterbrechungszustand zurückgesetzt werden. wenn ja für einen Thread, wenn die Unterbrechung auftritt, wird es auf eine Sperre wartet, dass es auch weiterhin für die Sperre warten. Wenn eine Sperre erhalten worden ist, wird es weiterhin. Also, wenn wir rufen Interrupt () -Methode, müssen Sie manuell erfassen, ob der Faden unterbrochen wird, und dann die entsprechende Behandlung.

6.3

Wenn der Thread aufwacht, muss die Anweisung erwachenden Verfahren werden synchronisierten Block oder synchronisiert werden , sonst wird es eine Ausnahme IllegalMonitorStateException Diese werfen, weil diese Methoden vor aufgerufen werden muss das Stromüberwachungsmonitor Zielobjekt zu erhalten, das heißt benachrichtigen / notifyAll und hängen Warte Methoden auf dem Monitor Objekte
und verschiedene Methoden des Schlafes nach dem Methodenaufruf abgeschlossen ist, warten ist, wird der Faden aufgehängt, aber das warten Methode wird die aktuelle Verriegelung durch den Monitor (Monitor) gehalten freizugeben, bis der Faden Anrufe benachrichtigt / nach notifyAll Methode kann nur fortgesetzt werden , aber in dem Schlaf Schlaf Methode entbindet nicht die Sperre Thread nur. Während der hinteren benachrichtigen / notifyAll Methodenaufrufe, und läßt nicht sofort den Sperrmonitor, aber () {} / synchronisierte Methode wird nach dem Ende der jeweiligen synchronisiert automatisch die Sperre nur dann durchgeführt.

Hierin durch Bezugnahme: [https://blog.csdn.net/javazejian/article/details/72828483?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task]

Veröffentlicht 47 Originalarbeiten · erntete Lob 15 · Ansichten 10000 +

Ich denke du magst

Origin blog.csdn.net/qq_41525021/article/details/104596262
Empfohlen
Rangfolge