Inhaltsverzeichnis
Was ist CAS
Spezifische Anwendungsszenarien
version
Heim Java javaLernprogramm So verwenden Sie CAS und Java Optimistic Locking

So verwenden Sie CAS und Java Optimistic Locking

May 01, 2023 pm 08:07 PM
java cas

Was ist CAS

CAS ist CompareAndSwap, was Vergleich und Austausch bedeutet. Warum verwendet CAS keine Sperren, gewährleistet aber dennoch eine sichere Datenmanipulation unter gleichzeitigen Bedingungen? Der Name zeigt das Prinzip von CAS tatsächlich sehr intuitiv. Der spezifische Prozess der Datenänderung ist wie folgt: #🎜🎜 #Wenn Sie CAS zum Bearbeiten von Daten verwenden, übergeben Sie den ursprünglichen Wert der Daten und den zu ändernden Wert an die Methode

  1. Vergleichen Sie, ob der aktuelle Zielvariablenwert vorliegt ist derselbe wie der ursprüngliche Wert, der in übergeben wurde

  2. Wenn sie gleich sind, bedeutet dies, dass die Zielvariable nicht von anderen Threads geändert wurde. Ändern Sie einfach die Zielvariable Wert direkt

  3. #🎜🎜 #Wenn sich der Zielvariablenwert vom ursprünglichen Wert unterscheidet, beweist dies, dass die Zielvariable von anderen Threads geändert wurde und diese CAS-Änderung fehlgeschlagen ist #🎜 🎜#

  4. Aus dem obigen Prozess können wir sehen, dass CAS tatsächlich garantiert ist, dass die Daten sicher geändert werden können, es besteht jedoch die Möglichkeit eines Fehlers bei der Änderung , die Änderung der Zielvariablendaten ist nicht erfolgreich. Zu diesem Zeitpunkt müssen wir eine Schleife durchlaufen, um das Ergebnis der CAS-Änderung der Daten zu ermitteln, und es erneut versuchen, wenn dies fehlschlägt.
  5. Studenten, die genauer nachdenken, befürchten möglicherweise, dass der Vergleichs- und Ersetzungsvorgang von CAS selbst Probleme mit der Parallelitätssicherheit verursacht. In tatsächlichen Anwendungen werden Vergleiche und Ersetzungen nicht durchgeführt JDK stellt mit Hilfe der Hardware-Ebene sicher, dass Vergleich und Substitution eine atomare Aktion sind.

CAS implementiert sperrenfreie Programmierung

Sperrenfreie Programmierung bezieht sich auf den sicheren Betrieb gemeinsamer Variablen ohne Verwendung von Sperren#🎜 🎜#In Bei der gleichzeitigen Programmierung verwenden wir verschiedene Sperren, um die Sicherheit gemeinsam genutzter Variablen zu gewährleisten. Das heißt, es ist garantiert, dass andere Threads nicht dieselbe gemeinsam genutzte Variable bearbeiten können, wenn ein Thread die Bedienung der gemeinsam genutzten Variablen noch nicht abgeschlossen hat.

Die korrekte Verwendung von Sperren kann die Datensicherheit bei Parallelität gewährleisten. Wenn jedoch der Grad der Parallelität nicht hoch ist und der Wettbewerb nicht hart ist, wird der Erwerb und die Freigabe von Sperren zu unnötiger Leistungsverschwendung. In diesem Fall können Sie die Verwendung von CAS in Betracht ziehen, um die Datensicherheit zu gewährleisten und eine sperrenfreie Programmierung zu erreichen. Der obige CAS-Vorgang weist jedoch immer noch Mängel auf. Angenommen, der Wert der gemeinsam genutzten Variablen, auf die der aktuelle Thread zugreift, ist A. Während Thread 1 auf die gemeinsam genutzte Variable zugreift, bedient Thread 2 die gemeinsam genutzte Variable und weist ihr den Wert B zu. Nachdem Thread 2 seine eigene Logik verarbeitet hat, wird er verwendet weist der gemeinsam genutzten Variablen den Wert A zu. Zu diesem Zeitpunkt vergleicht Thread 1 den Wert A der gemeinsam genutzten Variablen mit dem ursprünglichen Wert A, geht fälschlicherweise davon aus, dass kein anderer Thread die gemeinsam genutzte Variable betreibt, und gibt direkt den Erfolg der Operation zurück. Das ist das ABA-Problem. Obwohl sich die meisten Unternehmen nicht darum kümmern müssen, ob andere Änderungen an gemeinsam genutzten Variablen vorgenommen wurden, kann das korrekte Ergebnis erzielt werden, solange der ursprüngliche Wert mit dem aktuellen Wert übereinstimmt. Es gibt jedoch einige sensible Szenarien, in denen nicht nur die Das Ergebnis der gemeinsam genutzten Variablen ist gleichbedeutend damit, dass sie nicht geändert wird, aber es ist auch nicht akzeptabel, dass gemeinsam genutzte Variablen von anderen Threads im Prozess geändert werden. Glücklicherweise gibt es eine ausgereifte Lösung für das ABA-Problem. Wir fügen der gemeinsam genutzten Variablen eine Versionsnummer hinzu, und der Wert der Versionsnummer erhöht sich automatisch, wenn die gemeinsam genutzte Variable geändert wird. Bei der CAS-Operation vergleichen wir nicht den ursprünglichen Variablenwert, sondern die Versionsnummer der gemeinsam genutzten Variablen. Die für jede Operation mit gemeinsam genutzten Variablen aktualisierte Versionsnummer ist eindeutig, sodass das ABA-Problem vermieden werden kann.

Spezifische Anwendungsszenarien

CAS-Anwendung im JDKErstens ist es unsicher, wenn mehrere Threads gleichzeitig mit gewöhnlichen Variablen arbeiten Das Operationsergebnis kann von anderen Threads überschrieben werden. Jetzt verwenden wir zwei Threads, und jeder Thread erhöht den Anfangswert 1. Wenn kein Synchronisationsmechanismus vorhanden ist, ist das Ergebnis der gemeinsam genutzten Variablen wahrscheinlich kleiner als 3 sein. Das heißt, es ist möglich, dass sowohl Thread 1 als auch Thread 2 den Anfangswert 1 gelesen haben, Thread 1 ihn 2 zuweist und der von Thread 2 aus dem Speicher gelesene Wert, in dem er sich befindet, auch die Variable erhöht durch 1 und weist es 2 zu, sodass das Endergebnis 2 ist, was kleiner ist als das erwartete Ergebnis von 3. Die Inkrementierungsoperation ist keine atomare Operation, was zu dem unsicheren Problem der gemeinsam genutzten Variablenoperation führt. Um dieses Problem zu lösen, stellt JDK eine Reihe atomarer Klassen bereit, um entsprechende atomare Operationen bereitzustellen. Das Folgende ist der Quellcode der getAndIncrement-Methode in AtomicInteger. Schauen wir uns den Quellcode an, um zu sehen, wie man mit CAS die threadsichere atomare Addition von Ganzzahlvariablen implementiert.

<code>/**<br> * 原子性的将当前值增加1<br> *<br> * @return 返回自增前的值<br> */<br>public final int getAndIncrement() {<br>    return unsafe.getAndAddInt(this, valueOffset, 1);<br>}<br></code>
Nach dem Login kopieren
Sie können sehen, dass getAndIncrement tatsächlich die getAndAddInt-Methode der UnSafe-Klasse aufruft, um atomare Operationen zu implementieren. Das Folgende ist der getAndAddInt-Quellcode

<code>/**<br> * 原子的将给定值与目标字变量相加并重新赋值给目标变量<br> *<br> * @param o 要更新的变量所在的对象<br> * @param offset 变量字段的内存偏移值<br> * @param delta 要增加的数字值<br> * @return 更改前的原始值<br> * @since 1.8<br> */<br>public final int getAndAddInt(Object o, long offset, int delta) {<br>    int v;<br>    do {<br>    	// 获取当前目标目标变量值<br>        v = getIntVolatile(o, offset);<br>    // 这句代码是关键, 自旋保证相加操作一定成功<br>    // 如果不成功继续运行上一句代码, 获取被其他<br>    // 线程抢先修改的变量值, 在新值基础上尝试相加<br>    // 操作, 保证了相加操作的原子性<br>    } while (!compareAndSwapInt(o, offset, v, v + delta));<br>    return v;<br>}<br></code>
Nach dem Login kopieren

Wir sind alle mit Sperren vertraut, z. B. mit wiedereintrittsfähigen Sperren, die im Wesentlichen auf der AbstractQueuedSynchronizer-Klasse basieren Warteschlange. Die Atomizität von Operationen wird durch CAS garantiert. Der Quellcode lautet wie folgt: Uusafe-Klasse im JDK Zusätzlich zu Operationen können wir CAS-Ideen in der tatsächlichen Entwicklung verwenden, um einen sicheren Datenbankbetrieb unter gleichzeitigen Bedingungen sicherzustellen.

Angenommen, die Struktur und Daten der Benutzertabelle sind wie folgt. Das Versionsfeld ist der Schlüssel zur Implementierung einer optimistischen Sperre

id

user

coupon_num

version

# 🎜 🎜#1#🎜 🎜#朱小明00

假设我们有一个用户领取优惠券的按钮,怎么防止用户快速点击按钮造成重复领取优惠券的情况呢。我们要安全的更改id为1的用户的coupon_num优惠券数量,将version字段作为CAS比较的版本号,即可避免重复增加优惠券数量,比较和替换这个逻辑通过WHERE条件来实现. 涉及sql如下:

<code>UPDATE user <br>SET coupon_num = coupon_num + 1, version = version + 1 <br>WHERE version = 0</code>
Nach dem Login kopieren

可以看到,我们查询出id为1的数据, 版本号为0,修改数据的同时把当前版本号当做条件即可实现安全修改,如果修改失败,证明已经被其他线程修改过,然后看具体业务决定是否需要自旋尝试再次修改。这里要注意考虑竞争激烈的情况下多个线程自旋导致过度的性能消耗,根据并发量选择适合自己业务的方式

Das obige ist der detaillierte Inhalt vonSo verwenden Sie CAS und Java Optimistic Locking. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

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

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Beste grafische Einstellungen
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. So reparieren Sie Audio, wenn Sie niemanden hören können
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Quadratwurzel in Java Quadratwurzel in Java Aug 30, 2024 pm 04:26 PM

Leitfaden zur Quadratwurzel in Java. Hier diskutieren wir anhand eines Beispiels und seiner Code-Implementierung, wie Quadratwurzel in Java funktioniert.

Perfekte Zahl in Java Perfekte Zahl in Java Aug 30, 2024 pm 04:28 PM

Leitfaden zur perfekten Zahl in Java. Hier besprechen wir die Definition, Wie prüft man die perfekte Zahl in Java?, Beispiele mit Code-Implementierung.

Zufallszahlengenerator in Java Zufallszahlengenerator in Java Aug 30, 2024 pm 04:27 PM

Leitfaden zum Zufallszahlengenerator in Java. Hier besprechen wir Funktionen in Java anhand von Beispielen und zwei verschiedene Generatoren anhand ihrer Beispiele.

Armstrong-Zahl in Java Armstrong-Zahl in Java Aug 30, 2024 pm 04:26 PM

Leitfaden zur Armstrong-Zahl in Java. Hier besprechen wir eine Einführung in die Armstrong-Zahl in Java zusammen mit einem Teil des Codes.

Weka in Java Weka in Java Aug 30, 2024 pm 04:28 PM

Leitfaden für Weka in Java. Hier besprechen wir die Einführung, die Verwendung von Weka Java, die Art der Plattform und die Vorteile anhand von Beispielen.

Smith-Nummer in Java Smith-Nummer in Java Aug 30, 2024 pm 04:28 PM

Leitfaden zur Smith-Zahl in Java. Hier besprechen wir die Definition: Wie überprüft man die Smith-Nummer in Java? Beispiel mit Code-Implementierung.

Fragen zum Java Spring-Interview Fragen zum Java Spring-Interview Aug 30, 2024 pm 04:29 PM

In diesem Artikel haben wir die am häufigsten gestellten Fragen zu Java Spring-Interviews mit ihren detaillierten Antworten zusammengestellt. Damit Sie das Interview knacken können.

Brechen oder aus Java 8 Stream foreach zurückkehren? Brechen oder aus Java 8 Stream foreach zurückkehren? Feb 07, 2025 pm 12:09 PM

Java 8 führt die Stream -API ein und bietet eine leistungsstarke und ausdrucksstarke Möglichkeit, Datensammlungen zu verarbeiten. Eine häufige Frage bei der Verwendung von Stream lautet jedoch: Wie kann man von einem Foreach -Betrieb brechen oder zurückkehren? Herkömmliche Schleifen ermöglichen eine frühzeitige Unterbrechung oder Rückkehr, aber die Stream's foreach -Methode unterstützt diese Methode nicht direkt. In diesem Artikel werden die Gründe erläutert und alternative Methoden zur Implementierung vorzeitiger Beendigung in Strahlverarbeitungssystemen erforscht. Weitere Lektüre: Java Stream API -Verbesserungen Stream foreach verstehen Die Foreach -Methode ist ein Terminalbetrieb, der einen Vorgang für jedes Element im Stream ausführt. Seine Designabsicht ist

See all articles