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 }
Es wird von Java 5 in java.util.concurrent
.locks hinzugefügt API. 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
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.
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!