Heim > Java > javaLernprogramm > Beispielanalyse des Java-Schlüsselwortsynchronisierungsprinzips und des Sperrstatus

Beispielanalyse des Java-Schlüsselwortsynchronisierungsprinzips und des Sperrstatus

王林
Freigeben: 2023-05-11 15:25:06
nach vorne
796 Leute haben es durchsucht

1. Das Konzept der Sperre in Java

  • Spin-Sperre: Wenn ein Thread die Sperre erhält und die Sperre von anderen Threads erworben wurde, wartet der Thread in einer Schleife und ermittelt dann kontinuierlich, ob die Sperre vorliegt Wenn die Sperre erfolgreich erworben werden kann, wird die Schleife erst beendet, wenn die Sperre erworben wurde.

  • Optimistische Sperre: Unter der Annahme, dass kein Konflikt vorliegt. Wenn beim Ändern der Daten festgestellt wird, dass die Daten nicht mit den zuvor erhaltenen Daten übereinstimmen, lesen Sie die neuesten Daten und versuchen Sie die Änderung erneut.

  • Pessimistische Sperre: Gehen Sie davon aus, dass Parallelitätskonflikte auftreten, synchronisieren Sie alle datenbezogenen Vorgänge und beginnen Sie mit der Sperrung beim Lesen von Daten.

  • Exklusive Sperre (Schreiben): Fügen Sie der Ressource eine Schreibsperre hinzu, der Thread kann die Ressource ändern und andere Threads können sie nicht erneut sperren (einzelnes Schreiben).

  • Gemeinsame Sperre (Lesen): Nach dem Hinzufügen einer Lesesperre zu einer Ressource kann diese nur gelesen, aber nicht geändert werden. Andere Threads können nur Lesesperren hinzufügen und keine Schreibsperren (mehrfach) hinzufügen. Stellen Sie es sich einfach als Semaphor (Semaphor) vor.

  • Wiedereintrittssperren und nicht wiedereintrittsfähige Sperren: Nachdem ein Thread eine Sperre erhalten hat, kann er frei anderen Code eingeben, der durch dieselbe Sperre synchronisiert wird.

  • Gerechte Sperre und unfaire Sperre: Die Reihenfolge beim Wettbewerb um Sperren ist fair, wenn das Prinzip „Wer zuerst kommt, mahlt zuerst“ gilt. Das heißt, es handelt sich um ein faires Schloss, wenn die Reihenfolge beim Ergreifen des Schlosses und die Reihenfolge beim Ergreifen des Schlosses garantiert gleich sind.

2. Synchronisierte Schlüsselwortsynchronisierungsfunktionen

Funktionen: wiedereintrittsfähige, exklusive, pessimistische Sperre.

Sperrungsbezogene Optimierungen:

  • Sperrenbeseitigung: Die Parameter zum Aktivieren der Sperrenbeseitigung sind -XX:+DoEscapeAnalysis, -XX:+EliminateLocks. -XX:+DoEscapeAnalysis-XX:+EliminateLocks

  • 锁粗化:JDK做了锁粗化的优化,但我们自己可从代码层面优化。

1、锁消除示例

/**
 * 锁消除示例,JIT即时编译,进行了锁消除
 * @author 刘亚楼
 * @date 2020/1/16
 */
public class LockEliminationExample {
	/**
	 * StringBuilder线程不安全,StringBuffer用了synchronized关键字,是线程安全的
	 * 针对下面这种单线程加锁、解锁操作,JIT会进行优化,进行锁消除
	 */
	public static void eliminateLock() {
		StringBuffer stringBuffer = new StringBuffer();
		stringBuffer.append("a");
		stringBuffer.append("b");
		stringBuffer.append("c");
		stringBuffer.append("a");
		stringBuffer.append("b");
		stringBuffer.append("c");
		stringBuffer.append("a");
		stringBuffer.append("b");
		stringBuffer.append("c");
	}
}
Nach dem Login kopieren

2、锁粗化示例

/**
 * 锁粗化示例
 * @author 刘亚楼
 * @date 2020/1/16
 */
public class LockCoarseningExample {
	/**
	 * 针对下面这种无意义的加锁操作,JIT会进行优化,对变量i的所有操作放到一个同步代码块里
	 */
	public static void lockCoarsening() {
		int i = 0;
		synchronized (LockCoarseningExample.class) {
			i++;
		}
		synchronized (LockCoarseningExample.class) {
			i--;
		}
		synchronized (LockCoarseningExample.class) {
			i++;
		}
		synchronized (LockCoarseningExample.class) {
			i++;
			i--;
			i++;
		}
	}
}
Nach dem Login kopieren

备注:锁消除和锁粗化的区别在于锁消除是针对单个线程重复加解锁做的优化,最终没有锁的存在。而锁粗化不只是针对单线程,且最终还是有锁的存在。

三、synchronized关键字原理

1、关于Mark Word

首先,对象在堆中由对象头、实例数据和对齐填充组成。

对象头包含两部分信息,第一部分用于存储对象自身的运行时数据,如哈希码、GC分代年龄、锁状态标志、线程持有的锁、偏向锁id等,这部分数据官方称为"Mark Word"。

对象头的另一部分是类型指针,即对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。

synchronized实现的锁是通过改变对象头的"Mark Word"来实现的。

"Mard Word"在32位和64位的虚拟机(未开启压缩指针)中分别为32位和64位。32位虚拟机"Mark Word"如下:

Beispielanalyse des Java-Schlüsselwortsynchronisierungsprinzips und des Sperrstatus

2、锁的状态变化

(1) 无锁 → 轻量级锁

无锁变成轻量级锁时,多个线程会读取对象的对象头的无锁状态mark word内容,然后进行cas操作进行修改,预期值是无锁状态mark word内容,新值是轻量级锁状态mark word内容,若修改成功,Lock record address指向成功获取锁的线程的Lock Record

演示流程如下:

Beispielanalyse des Java-Schlüsselwortsynchronisierungsprinzips und des Sperrstatus

(2) 轻量级锁 → 重量级锁

由于未成功获取锁的线程会自旋,长时间自旋会消耗CPU资源,因此自旋到一定次数会进行锁升级,由轻量级锁转变为重量级锁。

重量级锁是通过object monitor(对象监视器)实现的,对象监视器包括entryList(锁池)、owner(持锁者)、waitSet(等待集合)等。

升级为重量级锁时对象头mark word的内容是monitor address(对象监视器地址),指向对象监视器。

演示流程如下:

Beispielanalyse des Java-Schlüsselwortsynchronisierungsprinzips und des Sperrstatus

备注:抢锁失败线程会进入entryList(锁池),在调用wait方法后,线程会进入waitSet(等待集合),waitSet中的线程被唤醒后会重新进入entryList。

(3) 关于偏向锁

加锁之后不解锁,针对单线程

所谓偏向就是偏心,单线程加锁之后就不再解锁,减少了加锁→业务处理→释放锁→加锁操作流程。

在JDK6以后,默认已经开启了偏向锁这个优化,通过JVM参数-XX:-UseBiasedLocking

Lock-Vergröberung: JDK hat die Lock-Vergröberung optimiert, aber wir können sie selbst auf Codeebene optimieren.

Beispielanalyse des Java-Schlüsselwortsynchronisierungsprinzips und des Sperrstatus

1. Beispiel für Sperrenbeseitigung

rrreee

2. Beispiel für Sperrenvergröberung

rrreee🎜Hinweis: Der Unterschied zwischen Sperrenbeseitigung und Sperrenvergröberung besteht für a Die durch das Entsperren durchgeführte Optimierung eliminiert letztendlich die Existenz von Sperren. Das Vergröbern von Sperren betrifft nicht nur einzelne Threads, sondern letztendlich gibt es immer noch Sperren. 🎜🎜3. Prinzip des synchronisierten Schlüsselworts🎜

1 Über Mark Word

🎜Erstens besteht das Objekt im Heap aus Objektkopf, Instanzdaten und Ausrichtungsauffüllung. 🎜🎜Der Objektheader enthält zwei Informationsteile. Der erste Teil wird zum Speichern der Laufzeitdaten des Objekts selbst verwendet, z. B. Hash-Code, Alter der GC-Generierung, Sperrstatusflag, vom Thread gehaltene Sperre, voreingenommene Sperren-ID usw Dieser Teil der Daten ist offiziell. Er heißt „Mark Word“. 🎜🎜Der andere Teil des Objektheaders ist der Typzeiger, der der Zeiger des Objekts auf seine Klassenmetadaten ist. Die virtuelle Maschine verwendet diesen Zeiger, um zu bestimmen, zu welcher Klasse das Objekt gehört. 🎜🎜Die von synchronisiert implementierte Sperre wird durch Ändern des „Mark Word“ des Objektheaders implementiert. 🎜🎜"Mard Word" ist 32-Bit und 64-Bit in 32-Bit- bzw. 64-Bit-Virtual Machines (komprimierte Zeiger sind nicht aktiviert). Die virtuelle 32-Bit-Maschine „Mark Word“ lautet wie folgt: 🎜🎜Java-Schlüsselwort Synchronisiertes Prinzip und Analyse von Beispielen für den Sperrstatus🎜

2. Änderungen des Sperrstatus

(1) Keine Sperre→ leichte Sperre
🎜Wenn keine Sperre zu einer leichten Sperre wird, mehrere Threads liest den Wortinhalt der sperrfreien Zustandsmarkierung des Objektheaders und führt dann cas-Operationen aus, um ihn zu ändern. Der erwartete Wert ist der Wortinhalt der sperrfreien Zustandsmarkierung, und der neue Wert ist a Lightweight-Sperre. Inhalt des Statusmarkierungsworts. Bei erfolgreicher Änderung verweist Sperrdatensatzadresse auf den Sperrdatensatz des Threads, der die Sperre erfolgreich erhalten hat. 🎜🎜Der Demonstrationsprozess ist wie folgt: 🎜🎜Prinzip und Sperrstatus der Java-Schlüsselwortsynchronisierung Beispielanalyse🎜
(2) Leichte Sperre→ Schwere Sperre
🎜Da der Thread, der die Sperre nicht erhalten kann, sich dreht, verbraucht die langfristige Drehung CPU-Ressourcen, sodass die Drehung einen bestimmten Wert erreicht limit Das Schloss wird mehrmals aufgerüstet, von einem leichten Schloss zu einem schweren Schloss. 🎜🎜Schwere Sperren werden über Objektmonitore implementiert, zu denen EntryList (Sperrpool), Eigentümer (Sperrhalter), WaitSet (Wartesatz) usw. gehören. 🎜🎜Beim Upgrade auf eine Schwergewichtssperre ist der Inhalt des Objekt-Header-Markierungsworts die Monitoradresse (Objektmonitoradresse), die auf den Objektmonitor verweist. 🎜🎜Der Demonstrationsprozess ist wie folgt: 🎜🎜Prinzip und Sperrstatus der Java-Schlüsselwortsynchronisierung Beispielanalyse🎜🎜Hinweis: Der Thread, der die Sperre nicht ergreifen kann, tritt in die EntryList (Sperrpool) ein. Nach dem Aufruf der Wartemethode tritt der Thread in das WaitSet (Wartesatz) ein. Der Thread im WaitSet wird erneut eingegeben -Geben Sie die Eintragsliste ein, nachdem Sie geweckt wurden. 🎜
(3) Über voreingenommene Sperren
🎜Kein Entsperren nach dem Sperren, für einzelne Threads🎜🎜Die sogenannte Voreingenommenheit bedeutet, dass nach Einzel-Thread-Sperren keine Entsperrung mehr erfolgt, was die Sperrung reduziert→Geschäftsverarbeitung&rarr ;Sperre aufheben→Betriebsprozess sperren. 🎜🎜Nach JDK6 ist die Bias-Lock-Optimierung standardmäßig aktiviert. Die Bias-Sperre ist über den JVM-Parameter -XX:-UseBiasedLocking deaktiviert. Wenn die Bias-Sperre aktiviert ist, kann nur ein Thread zugreifen die Sperre und erhalten Sie die Vorspannung. 🎜🎜Über das Bias Lock Mark Word lautet der Inhalt wie folgt: 🎜🎜🎜🎜

Das Bias-Flag ist beim ersten Mal nützlich, wird aber nutzlos, wenn es zu Konflikten kommt.

Das Wesentliche an einer voreingenommenen Sperre ist, dass sie keine Sperre aufweist. Wenn es keine Multi-Thread-Konkurrenz für die Sperre gibt, betrachtet die JVM sie als einen einzelnen Thread und es ist keine Synchronisierung erforderlich.

Bemerkungen: Um die Arbeit der JVM zu reduzieren, wird die Synchronisierung durch viele Vorgänge am unteren Rand der JVM implementiert. Wenn keine Konflikte vorliegen, müssen keine Synchronisierungsvorgänge durchgeführt werden.

(4) Vollständiger Schloss-Upgrade-Prozess

Wenn die Vorspannungssperre nicht aktiviert ist, wird der sperrfreie Zustand zuerst auf ein leichtes Schloss aufgerüstet, und das leichte Schloss wird bis zu einem gewissen Grad auf ein schweres Schloss aufgerüstet.

Wenn die voreingenommene Sperre aktiviert ist, gibt es zwei Situationen:

  • Wenn die Sperre nicht belegt ist, wird sie auf keine Sperre hochgestuft, und dann wird die Sperre ohne Sperre auf eine leichte Sperre hochgestuft und dann Das leichte Schloss wird zu einem schweren Schloss aufgerüstet.

  • Wenn das Schloss belegt ist, wird es zu einem leichten Schloss und dann von einem leichten Schloss zu einem schweren Schloss aufgerüstet.

Beispielanalyse des Java-Schlüsselwortsynchronisierungsprinzips und des Sperrstatus

Das obige ist der detaillierte Inhalt vonBeispielanalyse des Java-Schlüsselwortsynchronisierungsprinzips und des Sperrstatus. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:yisu.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage