Heim  >  Artikel  >  Java  >  Interpretation neuer Funktionen von Java8 – StampedLock

Interpretation neuer Funktionen von Java8 – StampedLock

零下一度
零下一度Original
2017-06-17 14:15:031407Durchsuche

Dieser Artikel führt eine vergleichende Analyse von synchronisiertem Lock bis zum neuen StampedLock in Java8 durch. Freunde, die sich für die neuen Funktionen von Java8, StampedLock, interessieren, sollten einen Blick darauf werfen.

Java8 ist wie ein Schatz. Eine kleine API-Verbesserung reicht aus, um einen Artikel zu schreiben, wie zum Beispiel die Synchronisierung, die schon immer ein altes Thema in der gleichzeitigen Multithread-Programmierung war Wenn die Anwendung fehlerhaft ist, bleibt sie hängen und stürzt ab, aber selbst dann haben Sie keine andere Wahl, da Sie die Richtigkeit der Informationen sicherstellen müssen. Daher wurde in diesem Artikel beschlossen, eine vergleichende Analyse von synchronisiertem Lock zum neuen StampedLock in Java 8 durchzuführen. Ich glaube, dass StampedLock nicht alle enttäuschen wird.

synchronized

Vor Java5 wurde die Synchronisierung hauptsächlich mit synchronisiert implementiert. Es ist ein Schlüsselwort in der Java-Sprache. Wenn es zum Ändern einer Methode oder eines Codeblocks verwendet wird, kann sichergestellt werden, dass höchstens ein Thread den Code gleichzeitig ausführt.

Es gibt vier verschiedene Synchronisationsblöcke:

1. Statische Methode

3 Block in

4. Synchronisierter Block in statischer Methode

Jeder sollte damit vertraut sein, daher werde ich nicht näher darauf eingehen


Zusammenfassung: Synchronized war schon immer eine Veteranenrolle in der gleichzeitigen Multithread-Programmierung. Viele Leute werden es jedoch als Schwergewichtssperre bezeichnen. Auch die Leistung wurde verbessert.

synchronized(this)
// do operation
}


Sperre

Es wird von Java 5 in java.util.concurrent

.locks hinzugefügt API.

Lock ist eine Schnittstelle. Die Kernmethoden sind lock(), unlock() und tryLock(). Die Implementierungsklassen umfassen ReentrantLock, ReentrantReadWriteLock.WriteLock; >ReentrantReadWriteLock, ReentrantLock und synchronisierte Sperren haben die gleiche Speichersemantik.

Anders als synchronisiert ist Lock vollständig in Java geschrieben und hat nichts mit der JVM-Implementierung auf Java-Ebene zu tun. Lock bietet einen flexibleren Sperrmechanismus und viele Funktionen, die synchronisiert nicht bieten, z. B. Sperrabstimmung, zeitgesteuertes Sperrenwarten und Interrupt-Sperrenwarten. Da die Sperre jedoch durch Code implementiert wird, muss unLock( ) verwendet werden, um sicherzustellen, dass die Sperre aufgehoben wird. in „finally“{}


Das Folgende ist ein Codebeispiel für Lock

Zusammenfassung: Flexibler und skalierbarer als der synchronisierte Sperrmechanismus, aber trotzdem synchronisiert Code ist einfacher zu schreiben


StampedLock
rwlock.writeLock().lock();
try {
// do operation
} finally {
rwlock.writeLock().unlock();
}

Es ist Java8 in java.util.concurrent .locks ist eine neue API. ReentrantReadWriteLock kann die Schreibsperre nur erhalten, wenn keine Lese-/Schreibsperre vorhanden ist. Dies kann verwendet werden, um pessimistisches Lesen (Pessimistic Reading) zu implementieren, d. h., wenn das Lesen während der Ausführung durchgeführt wird Oft muss eine andere Implementierung schreiben. Um die Synchronisierung aufrechtzuerhalten, kann die Lesesperre von ReentrantReadWriteLock nützlich sein.

Wenn es jedoch viele Lesevorgänge und wenige Schreibvorgänge gibt, kann die Verwendung von ReentrantReadWriteLock dazu führen, dass der Schreibthread auf ein Hungerproblem stößt, das heißt, der Schreibthread kann nicht konkurrieren, bis er gesperrt ist.

StampedLock-Steuersperre verfügt über drei Modi (Schreiben, Lesen, optimistisches Lesen). Ein StampedLock-Status besteht aus zwei Teilen: Version und Modus. Die Sperrerfassungsmethode gibt eine Nummer als Ticketstempel zurück, die den entsprechenden verwendet Sperrstatus Zeigt den Zugriff an und steuert ihn. Die Zahl 0 gibt an, dass keine Schreibsperre für den Zugriff berechtigt ist. Lesesperren werden in pessimistische Sperren und optimistische Sperren unterteilt.


Der sogenannte optimistische Lesemodus, das heißt, wenn es viele Lesevorgänge und wenige Schreibvorgänge gibt, können Sie optimistisch sein, dass die Wahrscheinlichkeit, dass Schreiben und Lesen gleichzeitig erfolgen, sehr gering ist , also Verwenden Sie die vollständige Lesesperre ohne Pessimismus. Das Programm kann nach dem Lesen der Daten durch Schreiben überprüfen, ob sich die Daten geändert haben, und dann Folgemaßnahmen ergreifen (die Änderungsinformationen erneut lesen oder

eine Ausnahme auslösen

). , diese kleine Verbesserung kann den Durchsatz des Programms erheblich verbessern! !


Das Folgende ist ein Beispiel für StampedLock, das von Java doc bereitgestellt wird

Zusammenfassung:

class Point {
 private double x, y;
 private final StampedLock sl = new StampedLock();
 void move(double deltaX, double deltaY) { // an exclusively locked method
  long stamp = sl.writeLock();
  try {
  x += deltaX;
  y += deltaY;
  } finally {
  sl.unlockWrite(stamp);
  }
 }
 //下面看看乐观读锁案例
 double distanceFromOrigin() { // A read-only method
  long stamp = sl.tryOptimisticRead(); //获得一个乐观读锁
  double currentX = x, currentY = y; //将两个字段读入本地局部变量
  if (!sl.validate(stamp)) { //检查发出乐观读锁后同时是否有其他写锁发生?
  stamp = sl.readLock(); //如果没有,我们再次获得一个读悲观锁
  try {
   currentX = x; // 将两个字段读入本地局部变量
   currentY = y; // 将两个字段读入本地局部变量
  } finally {
   sl.unlockRead(stamp);
  }
  }
  return Math.sqrt(currentX * currentX + currentY * currentY);
 }
//下面是悲观读锁案例
 void moveIfAtOrigin(double newX, double newY) { // upgrade
  // Could instead start with optimistic, not read mode
  long stamp = sl.readLock();
  try {
  while (x == 0.0 && y == 0.0) { //循环,检查当前状态是否符合
   long ws = sl.tryConvertToWriteLock(stamp); //将读锁转为写锁
   if (ws != 0L) { //这是确认转为写锁是否成功
   stamp = ws; //如果成功 替换票据
   x = newX; //进行状态改变
   y = newY; //进行状态改变
   break;
   }
   else { //如果不能成功转换为写锁
   sl.unlockRead(stamp); //我们显式释放读锁
   stamp = sl.writeLock(); //显式直接进行写锁 然后再通过循环再试
   }
  }
  } finally {
  sl.unlock(stamp); //释放读锁或写锁
  }
 }
 }

StampedLock ist günstiger als ReentrantReadWriteLock, was bedeutet, dass es weniger verbraucht. Leistungsvergleich zwischen StampedLock und ReadWriteLock

Das Bild unten wird mit ReadWritLock verglichen. Die Lesegeschwindigkeit beträgt ca 4 Mal, Schreiben ist 1x.

Das Bild unten zeigt, dass bei sechs Threads die Leseleistung Dutzende Male beträgt und die Schreibleistung ebenfalls fast das Zehnfache beträgt:

Die folgende Abbildung zeigt die Durchsatzverbesserung:

Zusammenfassung

1. Synchronisiert kann nicht nur durch einige Überwachungen überwacht werden Tools-Sperre, und wenn während der Codeausführung eine Ausnahme auftritt, gibt die JVM die Sperre automatisch frei.

2 Um die Sperre aufzuheben, müssen Sie unLock() eingeben. 3. StampedLock hat eine enorme Verbesserung im Durchsatz, insbesondere in Szenarien, in denen es immer mehr Lesethreads gibt

4. StampedLock verfügt über eine komplexe API, es ist leicht, andere Methoden zu missbrauchen;

5. Wenn es nur wenige Konkurrenten gibt, ist synchronisiert eine gute Allzweck-Sperrimplementierung.

6. Wenn das Thread-Wachstum geschätzt werden kann, ist ReentrantLock eine gute Allzweck-Sperrimplementierung;

Das obige ist der detaillierte Inhalt vonInterpretation neuer Funktionen von Java8 – StampedLock. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
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