Heim  >  Artikel  >  Java  >  Anfänger können auch mit BAT-Interviewern konkurrieren: CAS

Anfänger können auch mit BAT-Interviewern konkurrieren: CAS

Java后端技术全栈
Java后端技术全栈nach vorne
2023-08-24 15:09:211426Durchsuche

Vorwort

Extrateil der Java Concurrent Programming-SerieC A S (Vergleichen und tauschen), der Artikelstil ist immer noch voller Bilder und Texte, leicht zu verstehen, sodass der Leser einen verrückten Dialog mit dem Interviewer führen kann. C A S(Compare and swap),文章风格依然是图文并茂,通俗易懂,让读者们也能与面试官疯狂对线。

C A S作为并发编程必不可少的基础知识,面试时C A S也是个高频考点,所以说C A S是必知必会,本文将带读者们深入理解C A S

C A S ist ein Muss, dieser Artikel wird den Lesern ein tiefgreifendes Verständnis vermittelnC A S. 🎜

Gliederung

Anfänger können auch mit BAT-Interviewern konkurrieren: CAS

Grundlegende Konzepte von C A S

C A S(compareAndSwap)也叫比较交换,是一种无锁原子算法,映射到操作系统就是一条cmpxchg硬件汇编指令(保证原子性),其作用是让C P U将内存值更新为新值,但是有个条件,内存值必须与期望值相同,并且C A SDer Vorgang erfordert kein Umschalten zwischen Benutzermodus und Kernelmodus, und der Speicher wird direkt im Benutzermodus gelesen und geschrieben (bedeutet keine Blockierung/Thread). Kontextwechsel).

它包含V表示待更新的内存值,E表示预期值,N表示新值,当 V值等于E值时,才会将V值更新成N值,如果V值和E值不等,不做更新, 这就是一次3个参数C A S(V,E,N)V表示待更新的内存值,E表示预期值,N表示新值,当 V值等于E值时,才会将V值更新成N值,如果V值和E值不等,不做更新,这就是一次C A S的操作。

Anfänger können auch mit BAT-Interviewern konkurrieren: CAS

简单说,C A S

Anfänger können auch mit BAT-Interviewern konkurrieren: CAS

简单说,<span style="display: none;"></span>Wie C A S die Atomizität gewährleistet<p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;margin: 10px;line-height: 1.75;letter-spacing: 0.2em;font-size: 15px;word-spacing: 0.1em;">Atomizität bedeutet, dass eine oder mehrere Operationen in <code style="font-size: 14px;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px; margin- rechts: 2px;Rand links: 2px;Hintergrundfarbe: rgba(27, 31, 35, 0,05);Schriftfamilie: „Operator Mono“, Consolas, Monaco, Menlo, Monospace;Wortumbruch: break- all; color: rgb(255, 100, 65);">C P U verfügt über Funktionen, die während der Ausführung nicht unterbrochen werden können. Sie werden entweder ausgeführt oder nicht ausgeführt und können nicht in der Mitte ausgeführt werden (eine, die nicht unterbrochen werden kann). oder eine Folge von Operationen). C P U执行的过程中不被中断的特性,要么执行,要不执行,不能执行到一半(不可被中断的一个或一系列操作)。

为了保证C A S的原子性,C P U提供了下面两种方式

  • 总线锁定
  • 缓存锁定

总线锁定

总线(B U S)是计算机组件间的传输数据方式,也就是说C P U与其他组件连接传输数据,就是靠总线完成的,比如C P U

Um sicherzustellen, dass rgba(27, 31, 35, 0,05);Schriftfamilie: „Operator Mono“, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(255, 100, 65);">C A S s Atomizität, C P U bietet die folgenden zwei Methoden🎜
  • Busschleuse
  • Cache-Sperre
  • ul>

    🎜🎜Bus lock🎜 🎜 🎜

    🎜Bus (B U S) ist eine Methode zur Datenübertragung zwischen Computerkomponenten, d. h.C P U verbindet sich mit anderen Komponenten, um Daten zu übertragen, was per Bus erfolgt, wie zum Beispiel Anfänger können auch mit BAT-Interviewern konkurrieren: CAS

    总线锁定是指C P U使用了总线锁,所谓总线锁就是使用C P U提供的LOCK#信号,当C P U在总线上输出LOCK#信号时,其他C P U的总线请求将被阻塞。C P U使用了总线锁,所谓总线锁就是使用C P U提供的LOCK#信号,当C P U在总线上输出LOCK#信号时,其他C P U的总线请求将被阻塞。

    Anfänger können auch mit BAT-Interviewern konkurrieren: CAS

    缓存锁定

    总线锁定方式虽然保证了原子性,但是在锁定期间,会导致大量阻塞,增加系统的性能开销,所以现代C P U为了提升性能,通过锁定范围缩小的思想设计出了缓存行锁定(缓存行是C P UAnfänger können auch mit BAT-Interviewern konkurrieren: CAS

    缓存锁定

    🎜总线锁定方式虽然保证了原子性, 但是在锁定期间, 会导致大量阻塞, 增加系统的性能开销, 所以现代C P U 🎜缓存行是Die sogenannte Cache-Sperre bezieht sich auf C P U sperrt die C P U缓存行进行锁定,当缓存行中的共享变量回写到内存时,其他C P U会通过总线嗅探机制感知该共享变量是否发生变化,如果发生变化,让自己对应的共享变量缓存行失效,重新从内存读取最新的数据,缓存锁定是基于缓存一致性机制来实现的,因为缓存一致性机制会阻止两个以上C P U同时修改同一个共享变量(现代C P U基本都支持和使用缓存锁定机制)。

    C A S的问题

    C A S和锁都解决了原子性问题,和锁相比没有阻塞、线程上下文你切换、死锁,所以C A S要比锁拥有更优越的性能,但是C A S同样存在缺点。

    C A SCache-Zeile

    , ​​und wenn die gemeinsam genutzten Variablen in der Cache-Zeile in den Speicher zurückgeschrieben werden, wird otherC P U erkennt über den Bus-Sniffing-Mechanismus, ob sich die gemeinsam genutzte Variable geändert hat. Wenn ja Wenn sich die entsprechende Cache-Zeile für gemeinsam genutzte Variablen ändert, werden die neuesten Daten erneut aus dem Speicher gelesen. Die Cache-Sperre wird basierend auf dem Cache-Konsistenzmechanismus implementiert, da der Cache-Konsistenzmechanismus mehr als zwei C P UGrundsätzlich alle unterstützen und verwenden den Cache-Sperrmechanismus 🎜). 🎜<h1 data-tool="mdnice editor" style="margin-top: 30px;margin-bottom: 15px;font-weight: fett;font-size: 24px;"> <span style="display: none; "></span>C A S-Problem</h1>🎜<code style="font-size: 14px;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px; margin- links: 2px;Hintergrundfarbe: rgba(27, 31, 35, 0,05);Schriftfamilie: „Operator Mono“, Consolas, Monaco, Menlo, Monospace;Wortumbruch: break-all;Farbe: rgb( 255, 100, 65);">C A S und Sperren lösen beide das Atomizitätsproblem. Im Vergleich zu Sperren gibt es keine Blockierung, Thread-Kontextumschaltung und Deadlocks, daher C A S hat eine bessere Leistung als Sperren, aberC A S
    Same Es gibt Mängel. 🎜🎜ABA问题

只能保证一个共享变量原子操作

C A S只能针对一个共享变量使用,如果多个共享变量就只能使用锁了,当然如果你有办法把多个变量整成一个变量,利用C A S也不错,例如读写锁中state

🎜

Nur eine gemeinsam genutzte Variable kann garantiert werden Atomare Operationen

C A S kann nur für eine gemeinsam genutzte Variable verwendet werden. Wenn mehrere gemeinsam genutzte Variablen vorhanden sind, können Sie nur Sperren verwenden. Natürlich, wenn Sie Es gibt eine Möglichkeit, mehrere Variablen in eine Variable zu integrieren, indem Sie C A S ist auch gut, zum Beispiel in read-write lockDie hohen und niedrigen Zustandsbits. 🎜

Die Spin-Zeit ist zu lang

Wenn ein Thread die Sperre nicht erhält, wird er nicht blockiert und angehalten, sondern versucht nach einer gewissen Zeit erneut, die Sperre zu erlangen Art der Schleifenerfassung Der Mechanismus heißt Spin Lock (Spinlock). spinlock)。

自旋锁好处是,持有锁的线程在短时间内释放锁,那些等待竞争锁的线程就不需进入阻塞状态(无需线程上下文切换/无需用户态与内核态切换),它们只需要等一等(自旋),等到持有锁的线程释放锁之后即可获取,这样就避免了用户态和内核态的切换消耗。

自旋锁坏处显而易见,线程在长时间内持有锁,等待竞争锁的线程一直自旋,即CPU一直空转,资源浪费在毫无意义的地方,所以一般会限制自旋次数。

最后来说自旋锁的实现,实现自旋锁可以基于C A S实现,先定义lockValue对象默认值11代表锁资源空闲,0

Der Vorteil der Spin-Sperre besteht darin, dass der Thread, der die Sperre hält, die Sperre in kurzer Zeit aufhebt und die Threads, die auf die konkurrierende Sperre warten, nicht in den Blockierungszustand wechseln müssen (🎜Kein Thread-Kontextwechsel erforderlich/Kein Bedarf für Benutzermodus und Kernelmoduswechsel ), müssen sie nur warten (🎜spin), bis der Thread, der die Sperre hält, die Sperre aufhebt, bevor sie sie erwerben können, wodurch der Aufwand für den Wechsel zwischen Benutzermodus und vermieden wird Kernel-Modus. 🎜🎜Die Nachteile von Spin-Sperren liegen auf der Hand, und Threads, die auf konkurrierende Sperren warten, drehen sich weiter, d beschränkt. 🎜🎜Lassen Sie uns abschließend über die Implementierung von Spin Lock sprechen. Die Implementierung von Spin Lock kann auf C A S Implementierung, definieren Sie zuerst lockValueObjektstandardwert1,1 bedeutet, dass die Sperrressource frei ist, 0 bedeutet, dass die Sperrressource belegt ist, der Code lautet wie folgt🎜
public class SpinLock {
    
    //lockValue 默认值1
    private AtomicInteger lockValue = new AtomicInteger(1);
    
    //自旋获取锁
    public void lock(){

        // 循环检测尝试获取锁
        while (!tryLock()){
            // 空转
        }

    }
    
    //获取锁
    public boolean tryLock(){
        // 期望值1,更新值0,更新成功返回true,更新失败返回false
        return lockValue.compareAndSet(1,0);
    }
    
    //释放锁
    public void unLock(){
        if(!lockValue.compareAndSet(1,0)){
            throw new RuntimeException("释放锁失败");
        }
    }

}

Die AtomicInteger类型的lockValue变量,AtomicIntegerJava基于C A S实现的Integer原子操作类,还定义了3个函数lock、tryLock、unLock

tryLock-Funktion ist oben definiert – Erwerben Sie die Sperre

  • 期望值1,更新值0
  • C A S更新C A S更新
  • 如果期望值与lockValue值相等,则lockValue值更新为0,返回true,否则执行下面逻辑
  • 如果期望值与lockValue值不相等,不做任何更新,返回false

如果期望值与lockValue值相等,则lockValue值更新为0,返回lockValueSie können es auch verwenden : 2px;Rand links: 2px;Hintergrundfarbe: rgba(27, 31, 35, 0,05);Schriftfamilie: „Operator Mono“, Consolas, Monaco, Menlo, Monospace;Wortumbruch: break-all;Farbe : rgb(255, 100, 65);">false🎜🎜🎜🎜🎜unLock函数-释放锁🎜

  • 期望值0,更新值0,更新值1
  • C A S更新
  • 如果期望值与lockValue值相等,则lockValue值更新为1,返回true,否则执行下面逻辑
  • 如果期望值与lockValue值不相等,不做任何更新,返回false

lockValue值相等,则1,返回true,否则执行下面逻辑🎜🎜🎜🎜 🎜🎜如果期望值与false🎜🎜🎜🎜🎜lock函数-自旋获取锁🎜<ul class="list-paddingleft-2" data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;list-style-type: square;"><li><section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"><strong style="color: black;">Ausführung<code style='overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(255, 100, 65);'>tryLock函数,返回true停止,否则一直循环

Anfänger können auch mit BAT-Interviewern konkurrieren: CAS

从上图可以看出,只有tryLock成功的线程(lockValue更新为0),才会执行代码块,其他线程个tryLock自旋等待lockValue被更新成1tryLock成功的线程执行unLocklockValue更新为1),自旋的线程才会tryLockerfolgreich.

ABA-Problem

C A S需要检查待更新的内存值有没有被修改,如果没有则更新,但是存在这样一种情况,如果一个值原来是A,变成了B,然后又变成了A,在C A SWenn Sie nachsehen, werden Sie feststellen, dass es nicht geändert wurde.

Angenommen, es gibt zwei Threads, Thread 1读取到内存值A,线程1时间片用完,切换到线程2,线程2也读取到了内存值A,并把它修改为B值,然后再把B值还原到A值,简单说,修改次序是A->B->A,接着线程1恢复运行,它发现内存值还是A,然后执行C A S操作,这就是著名的ABA ist ein Problem, aber es scheint, dass es kein Problem gibt.

Es handelt sich nur um eine einfache Datenstruktur, daher wird es wirklich keine Probleme geben. Wenn es sich um eine komplexe Datenstruktur handelt, kann es zu Problemen kommen (Verwenden Sie AtomicReference可以把C A S使用在对象上),以链表数据结构为例,两个线程通过C A S去删除头节点,假设现在链表有A->BKnoten

Anfänger können auch mit BAT-Interviewern konkurrieren: CAS
  • 线程B节点成为头节点,正要执行 2A节点,B节点成为头节点,正要执行C A S(A,A,B)时,时间片用完,切换到线程2
  • 线程2删除A、B节点
  • 线程2加入C、A节点,链表节点变成A->C
  • 线程1重新获取时间片,执行C A S(A,A,B)
  • 丢失C
  • 🎜线程A、B节点🎜🎜🎜🎜线程A->C🎜🎜🎜🎜线程C A S(A, A,B)🎜🎜🎜🎜丢失Um die Lösung zu findenA B A问题也非常简单,只要追加版本号即可,每次改变时加1,即A —> B —> A,变成1A —> 2B —> 3A,在Java中提供了AtomicStampedRdference可以实现这个方案(面试只要问了C A S,就一定会问ABA, muss dies verstanden werden).

Das obige ist der detaillierte Inhalt vonAnfänger können auch mit BAT-Interviewern konkurrieren: CAS. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:Java后端技术全栈. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen