Der Interviewer fragt Sie: Wissen Sie, was ein ABA-Problem ist?
„Die Zibetkatze tauscht sich gegen den Prinzen aus.“ Die damals geliebten Konkubinen Konkubine Liu und Konkubine Li sind alle schwanger. Es ist offensichtlich, dass jeder, der einen Sohn zur Welt bringt, der Hauptpalast werden kann. Konkubine Liu war schon lange eifersüchtig und befürchtete, dass Konkubine Li einen Sohn zur Welt bringen und zur Königin ernannt werden würde, also schmiedete sie einen Plan mit Guo Huai, dem Palastverwalter Dutang, und in Zusammenarbeit mit der Hebamme Youshi, Konkubine Li starb während der Geburt im Koma. Unerwarteterweise wurde einer Zibetkatze das Fell abgezogen, es war blutig und glänzend und nahm den neugeborenen Prinzen mit. Konkubine Liu befahl der Palastmagd Kou Zhu, den Prinzen zu erwürgen, und übergab den Prinzen heimlich dem Eunuchen. Chen Lin steckte den Prinzen in einen Koffer und schickte ihn zu den Acht weisen Königen um ihn zu erziehen. Außerdem sah Zhenzong die gehäutete Zibetkatze und dachte, dass Konkubine Li ein Monster zur Welt gebracht hatte, also degradierte er sie in den kalten Palast. Bald hatte Konkubine Liu Wehen und gebar einen Sohn, der zum Prinzen ernannt wurde und ebenfalls zur Königin ernannt wurde. Sechs Jahre später starb Königin Lius Sohn unerwartet an einer Krankheit. Zhenzong hatte keine Erben mehr, also adoptierte er den Sohn seines älteren Bruders Baxian Wang (eigentlich der Prinz, der in diesem Jahr ersetzt worden war) als seinen Adoptivsohn und ernannte ihn zum Kronprinzen.
Aus dieser Geschichte geht hervor, dass der Prinz bei seiner Geburt durch eine Zibetkatze ersetzt wurde und durch eine seltsame Kombination von Umständen schließlich zurückkehrte, um der Prinz zu werden. Obwohl das Ergebnis das gleiche ist, ist der Prozess voller Wendungen und der Prinz hat wirklich ein schlimmes Schicksal. Warum diese Geschichte erzählen? Tatsächlich hat es viel mit dem Thema zu tun, das wir heute vorstellen werden. Beim gleichen Ergebnis weiß ich nicht, wie viele Operationen in der Mitte stattgefunden haben. Können wir also denken, dass sich daran nichts geändert hat? In verschiedenen Geschäftsszenarien müssen wir dieses Problem sorgfältig prüfen.
ABA-ProblembeschreibungIn einem Multithread-Szenario
Problem gibt es hier eine einfache Wissenschaft zum ABA-Problem. Beispielsweise gibt es zwei Threads, die CAS-Operationen mit demselben Wert ausführen (Anfangswert). A) gleichzeitig. Die drei Threads lauten wie folgt:Thread 1, der erwartete Wert ist A, der zu aktualisierende Wert ist B Thread 2, der erwartete Wert ist A, der zu aktualisierende Wert ist B
Thread 1 erhält die CPU-Zeitscheibe Zuerst erhält Thread 2 aus anderen Gründen zuerst die CPU-Zeitscheibe. Der Grund ist blockiert. Der Wert von Thread 1 wird mit dem erwarteten Wert von A verglichen. Es wird festgestellt, dass er gleich ist, und dann wird der Wert auf B aktualisiert Zu diesem Zeitpunkt erscheint Thread 3, der erwartete Wert ist B, der zu aktualisierende Wert ist A und der Wert von Thread 3 ist derselbe wie der erwartete Wert. Vergleichen Sie den Wert B und aktualisieren Sie ihn, wenn festgestellt wird, dass er gleich ist der Wert auf A. Zu diesem Zeitpunkt erholt sich Thread 2 von der Blockierung und erhält die CPU-Zeitscheibe. Zu diesem Zeitpunkt wird der Wert von Thread 2 mit dem erwarteten Wert A verglichen. Wenn festgestellt wird, dass er gleich ist, wird der Wert aktualisiert zu B. Obwohl Thread 2 den Vorgang ebenfalls abgeschlossen hat, weiß Thread 2 nicht, dass der Wert den Änderungsprozess von A->B->A durchlaufen hat.
Gib mir ein konkretes Beispiel
Xiao Ming hat 50 Yuan vom Geldautomaten abgehoben, es gab zwei Threads und der Kontostand wurde gleichzeitig von 100 auf 50 geändert Zeit:
-
Thread 1 (Geldautomat): Aktuellen Wert 100 abrufen, Aktualisierung auf 50 erwarten; Thread 2 (Geldautomat): Aktuellen Wert 100 abrufen, Aktualisierung auf 50 erwarten; Thread 1 erfolgreich ausgeführt, Thread 2 ist aus irgendeinem Grund blockiert; Zu diesem Zeitpunkt überweist jemand 50 an Xiao Ming; Thread 3 (Standard): Holen Sie sich den aktuellen Wert von 50 und erwarten Sie ihn auf 100 aktualisiert werden. Zu diesem Zeitpunkt wird Thread 3 erfolgreich ausgeführt und der Kontostand wird 100; Thread 2 erholt sich vom Block und erhält 100. Nach dem Vergleich wird der Kontostand weiterhin auf 50 aktualisiert.
An dieser Stelle können Sie sehen, dass der tatsächliche Saldo sein sollte: 100(100-50+50)
,但是实际上变为了50(100-50+50-50)
Dies ist das ABA-Problem, das zu falschen Einreichungsergebnissen führt.
Lösung
Um das ABA-Problem zu lösen, können Sie eine Versionsnummer hinzufügen. Jedes Mal, wenn der Wert des Speicherorts V geändert wird, wird die Versionsnummer um 1 erhöht
Codebeispiel
ABA-Probleme durch AtomicStampedReference lösen
AtomicStampedReference behält den Objektwert und die Versionsnummer intern bei den Anfangswert übergeben und ursprüngliche Version Nr.;
Wenn AtomicStampedReference den Objektwert festlegt, müssen sowohl der Objektwert als auch der Statusstempel den erwarteten Wert erfüllen, damit der Schreibvorgang erfolgreich ist.
private static AtomicStampedReference<Integer> atomicStampedReference = new AtomicStampedReference<Integer>(100,1); public static void main(String[] args) { //第一个线程 new Thread(() -> { System.out.println("t1拿到的初始版本号:" + atomicStampedReference.getStamp()); //睡眠1秒,是为了让t2线程也拿到同样的初始版本号 try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } atomicStampedReference.compareAndSet(100, 101,atomicStampedReference.getStamp(),atomicStampedReference.getStamp()+1); atomicStampedReference.compareAndSet(101, 100,atomicStampedReference.getStamp(),atomicStampedReference.getStamp()+1); },"t1").start(); // 第二个线程 new Thread(() -> { int stamp = atomicStampedReference.getStamp(); System.out.println("t2拿到的初始版本号:" + stamp); //睡眠3秒,是为了让t1线程完成ABA操作 try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("最新版本号:" + atomicStampedReference.getStamp()); System.out.println(atomicStampedReference.compareAndSet(100, 2019,stamp,atomicStampedReference.getStamp() + 1) + "\t当前值:" + atomicStampedReference.getReference()); },"t2").start(); }
1. Threads t1 und t2 erhalten die gleiche anfängliche Versionsnummer
3. Thread t1 schließt den ABA-Vorgang ab und die Versionsnummer wird auf 3
4 erhöht . Thread t2 Der CAS-Vorgang ist zu 3 geworden, was nicht mit der Versionsnummer 1 übereinstimmt, die zuvor von Thread t2 erhalten wurde. Das Ergebnis der Ausführung:
Lösen Sie das ABA-Problem durch AtomicMarkableReference
, Der einzige Unterschied zwischen AtomicMarkableReference besteht darin, dass zur Identifizierung der Referenz nicht mehr int verwendet wird, sondern eine boolesche Variable verwendet wird, um anzugeben, ob die Referenzvariable geändert wurde.
t1拿到的初始版本号:1 t2拿到的初始版本号:1 最新版本号:3 false 当前值:100
4. Thread t2 hat den CAS-Vorgang abgeschlossen. Die Versionsnummer ist nicht gleich der von Thread t2 zuvor erhaltenen Versionsnummer
AtomicStampedReference
可以给引用加上版本号,追踪引用的整个变化过程,如:A -> B -> C -> D -> A,通过AtomicStampedReference,我们可以知道,引用变量中途被更改了3次。但是,有时候,我们并不关心引用变量更改了几次,只是单纯的关心是否更改过,所以就有了AtomicMarkableReference
t1版本号是否被更改:false t2版本号是否被更改:false 是否更改过:true false 当前值:100Nach dem Login kopieren多说几句
以上是本期关于CAS领域的一个经典ABA问题的解析,不知道你在实际的工作中有没有遇到过,但是在面试中这块是并发知识考查的重点。如果你还没接触过此类的问题,我的建议是你自己将上面的代码运行一下,结合理论去理解一下ABA问题所带来的问题以及如何解决他,这对你日后的开发工作也是有莫大的帮助的!
Das obige ist der detaillierte Inhalt vonDer Interviewer fragt Sie: Wissen Sie, was ein ABA-Problem ist?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen



PHP-Sicherheitsüberprüfung durch CAS (CentralAuthenticationService) Mit der rasanten Entwicklung des Internets werden Benutzerrechteverwaltung und Identitätsüberprüfung immer wichtiger. Bei der Entwicklung von Webanwendungen ist es von entscheidender Bedeutung, Benutzerdaten zu schützen und unbefugten Zugriff zu verhindern. Um dieses Ziel zu erreichen, können wir CAS (CentralAuthenticationService) zur PHP-Sicherheitsüberprüfung verwenden. CAS

1. Erklären Sie, dass, wenn mehrere Threads gleichzeitig CAS-Operationen für eine Ressource ausführen, nur ein Thread erfolgreich ist, andere Threads jedoch nicht blockiert werden und andere Threads nur ein Signal erhalten, dass die Operation fehlgeschlagen ist. Es ist ersichtlich, dass CAS tatsächlich eine optimistische Sperre ist. 2. Wenn wir dem AtomInteger-Code folgen, können wir feststellen, dass letztendlich sum.misc.Unsafe aufgerufen wird. Schauen Sie sich den Namen „Unsafe“ an. Dabei handelt es sich um eine unsichere Klasse, die genau die richtigen Lücken in den Klassen- und Sichtbarkeitsregeln von Java ausnutzt. Aus Gründen der Geschwindigkeit geht Unsafe einige Kompromisse bei den Sicherheitsstandards von Java ein. publicfinalnativebooleancompareAndSwapInt(Objec

CAS-Erklärung: CAS (compareandswap), vergleichen und austauschen. Ein Mechanismus, der den durch die Verwendung von Sperren in Situationen mit mehreren Threads verursachten Leistungsverlust beheben kann. Die CAS-Operation enthält drei Operanden: Speicherort (V), erwarteter Originalwert (A) und neuer Wert (B). Wenn der Wert eines Speicherorts mit dem erwarteten Originalwert übereinstimmt, aktualisiert der Prozessor den Ort automatisch auf den neuen Wert. Ansonsten macht der Prozessor nichts. Ein Thread ruft den Num-Wert aus dem Hauptspeicher ab und verarbeitet Num. Beim Schreiben des Werts vergleicht der Thread den ersten Num-Wert mit dem Num-Wert im Hauptspeicher. Wenn sie gleich sind, ist der geänderte Wert Num Wenn sie nicht gleich sind, wird der Vergleich wiederholt, bis er erfolgreich ist. Hergestellt von CAS

Gesperrte Parallelität Für die meisten Programmierer (natürlich bin ich im Grunde einer von ihnen) ist gleichzeitiges Programmieren fast gleichbedeutend mit dem Hinzufügen einer Sperre (Mutex) zur relevanten Datenstruktur. Wenn wir beispielsweise einen Stapel benötigen, der Parallelität unterstützt, besteht die einfachste Möglichkeit darin, eine Sperre std::sync::Mutex zu einem Single-Threaded-Stack hinzuzufügen. (Arc wird hinzugefügt, um mehreren Threads den Besitz des Stapels zu ermöglichen) usestd::sync::{Mutex,Arc};#[derive(Clone)]structConcurrentStack{inner:Arc,}implConcurrentStack{pubfnnew()-> Self{

Was CASCAS ist, ist CompareAndSwap, also Vergleichen und Tauschen. Warum verwendet CAS keine Sperren, gewährleistet aber dennoch den sicheren Betrieb von Daten unter gleichzeitigen Bedingungen? Daten und der zu ändernde Wert werden an die Methode übergeben, um zu vergleichen, ob der aktuelle Zielvariablenwert mit dem ursprünglich übergebenen Wert übereinstimmt. Wenn sie identisch sind, bedeutet dies, dass die Zielvariable nicht von anderen Threads geändert wurde . Ändern Sie einfach den Zielvariablenwert direkt, dann beweisen Sie, dass die Zielvariable von anderen Threads geändert wurde. Aus dem obigen Prozess können wir ersehen garantiert tatsächlich eine sichere Änderung der Daten, es gibt jedoch Fälle, in denen die Änderung fehlschlägt.

Im Programm habe ich 100 Threads erstellt und jeder Thread hat 10.000 Operationen für die gemeinsam genutzte Variable inc gesammelt. Wenn es synchron ausgeführt wird, sollte der Endwert von inc 1.000.000 sein, aber wir wissen, dass das Programm beim Multithreading gleichzeitig ausgeführt wird Das heißt, verschiedene Threads können gleichzeitig denselben Wert aus dem Hauptspeicher lesen.

1. Erstellen Sie ein neues Springboot-Projekt und führen Sie die Abhängigkeit org.jasig.cas.clientcas-client-support-springboot3.6.22 ein. Konfigurieren Sie das @EnableCasClient-Annotationspaketcom.codetiler.demo;importorg.jasig.cas.client.boot.configuration. EnableCasClient;importorg.springframework.boot.SpringApplication;importorg.spring

In dieser Ausgabe geht es um die Analyse eines klassischen ABA-Problems im CAS-Bereich. Ich weiß nicht, ob Sie in der tatsächlichen Arbeit darauf gestoßen sind, aber dies ist der Schwerpunkt des Parallelitätswissenstests im Interview. Wenn Sie noch nicht auf ein solches Problem gestoßen sind, empfehle ich Ihnen, den obigen Code selbst auszuführen.
