Maison  >  Article  >  Java  >  Les novices peuvent également rivaliser avec les enquêteurs BAT : CAS

Les novices peuvent également rivaliser avec les enquêteurs BAT : CAS

Java后端技术全栈
Java后端技术全栈avant
2023-08-24 15:09:211424parcourir

Avant-propos

Partie supplémentaire de la série de programmation simultanée JavaC A S (Comparer et échanger), le style de l'article est toujours plein d'images et de textes, faciles à comprendre, permettant aux lecteurs d'avoir un dialogue fou avec l'intervieweur. C A S(Compare and swap),文章风格依然是图文并茂,通俗易懂,让读者们也能与面试官疯狂对线。

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

C A S code>En tant que connaissance de base essentielle de la programmation concurrente, lors de l'entretien<code style="font-size: 14px;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px; marge gauche : 2 px ; couleur d'arrière-plan : rgba (27, 31, 35, 0,05) ; famille de polices : « Operator Mono », Consolas, Monaco, Menlo, monospace ; coupure de mot : break-all ; couleur : rgb ( 255, 100, 65);">C A S est également un site de test à haute fréquence, donc C A S est un incontournable, cet article donnera aux lecteurs une compréhension approfondieC A S. 🎜

Outline

Les novices peuvent également rivaliser avec les enquêteurs BAT : CAS

Concepts de base de C A S

C A S(compareAndSwap)也叫比较交换,是一种无锁原子算法,映射到操作系统就是一条cmpxchg硬件汇编指令(保证原子性),其作用是让C P U将内存值更新为新值,但是有个条件,内存值必须与期望值相同,并且C A SL'opération ne nécessite pas de basculer entre le mode utilisateur et le mode noyau, et la mémoire est lue et écrite directement en mode utilisateur ( signifie pas de blocage/thread changement de contexte).

它包含3个参数<code style="font-size: 14px;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color : rgba(27, 31, 35, 0.05);famille de polices : " operator mono consolas monaco menlo monospace de mot break-all rgb> C A S(V,E,N)V表示待更新的内存值,E表示预期值,N表示新值,and V值等于E值时,才会将V值更新成N值,如果V值和E值不等,不做更新,这就是一次C A S的操作。3个参数C A S(V,E,N)V表示待更新的内存值,E表示预期值,N表示新值,当 V值等于E值时,才会将V值更新成N值,如果V值和E值不等,不做更新,这就是一次C A S的操作。

Les novices peuvent également rivaliser avec les enquêteurs BAT : CAS

简单说,C A S

Les novices peuvent également rivaliser avec les enquêteurs BAT : CAS

简单说,C A S想象的那样,说明它已经被别人修改过了,你只需要重新读取,设置新期望值,再次尝试修改就好了。🎜

Comment C A S garantit l'atomicité

L'atomicité signifie qu'une ou plusieurs opérations sont dans C P U fonctionnalités qui ne peuvent pas être interrompues pendant l'exécution. Il est soit exécuté, soit non exécuté, et ne peut pas être exécuté au milieu (celui qui ne peut pas être interrompu ou une séquence d'opérations). C P U执行的过程中不被中断的特性,要么执行,要不执行,不能执行到一半(不可被中断的一个或一系列操作)。

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

  • 总线锁定
  • 缓存锁定

总线锁定

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

Afin de garantir rgba (27, 31, 35, 0,05) ; famille de polices : « Operator Mono », Consolas, Monaco, Menlo, monospace ; 65);">Atomicité de C A S , C P U fournit les deux méthodes suivantes🎜
  • Verrouillage du cache
  • ul>

    🎜🎜Verrouillage du bus🎜 🎜 🎜

    🎜Bus (B U S) est une méthode de transmission de données entre composants informatiques, c'est-à-direC P U se connecte à d'autres composants pour transmettre des données, ce qui se fait par bus, tel que C P U lit et écrit la mémoire. 🎜
    Les novices peuvent également rivaliser avec les enquêteurs BAT : 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的总线请求将被阻塞。

    Les novices peuvent également rivaliser avec les enquêteurs BAT : CAS

    缓存锁定

    总线锁定方式虽然保证了原子性,但是在锁定期间,会导致大量阻塞,增加系统的性能开销,所以现代C P U为了提升性能,通过锁定范围缩小的思想设计出了缓存行锁定(缓存行是C P ULes novices peuvent également rivaliser avec les enquêteurs BAT : CAS

    缓存锁定

    🎜增加系统的性能开销,所以现代C P U为了提升性能,通过锁定范围缩小的思想设计出了缓存行锁定(🎜缓存行是C P U高速缓存存储的最小单位🎜)。🎜

    Le soi-disant verrouillage du cache fait référence à C P U verrouille la 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 Sligne de cache

    , et lorsque les variables partagées dans la ligne de cache sont réécrites en mémoire, d'autres C P U détectera si la variable partagée a changé via le mécanisme de détection de bus. Si elle changements, laissez-vous La ligne de cache de variable partagée correspondante n'est pas valide et les dernières données sont à nouveau lues à partir de la mémoire. Le verrouillage du cache est implémenté sur la base du mécanisme de cohérence du cache, car le mécanisme de cohérence du cache empêchera plus de deux C P UModifier simultanément la même variable partagée (🎜ModernC P U Fondamentalement, tous prennent en charge et utilisent le mécanisme de verrouillage du cache 🎜). 🎜<h1 data-tool="mdnice editor" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 24px;"> <span style="display: none; "></span>Problème C A S</h1>🎜<code style="font-size: 14px;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px; margin- gauche : 2px ; couleur d'arrière-plan : rgba (27, 31, 35, 0,05) ; famille de polices : « Operator Mono », Consolas, Monaco, Menlo, monospace ; saut de mot : break-all ; couleur : rgb ( 255, 100, 65);">C A S et les verrous résolvent tous deux le problème de l'atomicité. Par rapport aux verrous, il n'y a pas de blocage, de changement de contexte de thread et de blocages, donc C A S a de meilleures performances que les verrous, maisC A SIdem Il y a des défauts. 🎜🎜C A S Le problème avec le code> est le suivant🎜<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;">ne peut garantir que le fonctionnement atomique d'une variable partagée</strong></section></li> <li><section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"><strong style="color: black;">Le temps de rotation est trop long (basé sur le verrouillage de rotation)</strong></section></li> <li><section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"><strong style="color: black;"><code style="overflow-wrap: break -word ;remplissage : 2px 4px;rayon de bordure : 4px;marge droite : 2px;marge gauche : 2px;couleur d'arrière-plan : rgba(27, 31, 35, 0,05);famille de polices : " operator mono consolas monaco menlo monospace de mot break-all rgb>ABAQuestionABA问题

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

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

    🎜

    Une seule variable partagée peut être garantie Opérations atomiques

    C A S

    ne peut être utilisé que pour une seule variable partagée. S'il existe plusieurs variables partagées, vous ne pouvez utiliser que des verrous. Bien sûr, si Il existe un moyen d'intégrer plusieurs variables dans une seule variable, en utilisant C A S est également bon, par exemple en verrouillage lecture-écritureLes bits d'état haut et bas. 🎜

    Le temps de rotation est trop long

    Lorsqu'un thread ne parvient pas à acquérir le verrou, il ne se bloque pas et ne se suspend pas, mais essaie de l'acquérir à nouveau après un certain temps jusqu'à ce qu'il réussisse. type d'acquisition de boucle Le mécanisme est appelé spin lock (spinlock). spinlock)。

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

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

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

    L'avantage du verrouillage tournant est que le thread qui maintient le verrou libère le verrou en peu de temps, et les threads qui attendent le verrou concurrent n'ont pas besoin d'entrer dans l'état de blocage (🎜Pas besoin de changement de contexte de thread/Pas besoin de changement de mode utilisateur et de mode noyau ), il leur suffit d'attendre (🎜tourner) que le thread détenant le verrou libère le verrou avant de pouvoir l'acquérir, évitant ainsi la consommation de commutation entre le mode utilisateur et le mode noyau. mode noyau. 🎜🎜Les inconvénients des verrous tournants sont évidents. Les threads détiennent les verrous pendant longtemps, et les threads en attente de verrous concurrents continuent de tourner, c'est-à-dire que le processeur continue de tourner au ralenti et que les ressources sont gaspillées dans des endroits dénués de sens, de sorte que le nombre de tours est généralement élevé. limité. 🎜🎜Enfin, parlons de l'implémentation du spin lock. L'implémentation du spin lock peut être basée sur C A S implémentation, définissez d'abord lockValueValeur par défaut de l'objet1,1 signifie que la ressource de verrouillage est libre, 0 signifie que la ressource de verrouillage est occupée, le code est le suivant🎜
    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("释放锁失败");
            }
        }
    
    }

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

    tryLock est définie ci-dessus - acquérir le verrou

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

    如果期望值与lockValue值相等,则lockValue值更新为0,返回 true, -gauche : 2 px ; couleur d'arrière-plan : rgba (27, 31, 35, 0,05) ; famille de polices : "Operator Mono", Consolas, Monaco, Menlo, monospace ; coupure de mot : break-all ; couleur : rgb (255 , 100, 65);">lockValue值不相等,不做任何更新,返回false

    🎜🎜🎜🎜unLock函数-释放锁🎜
    • 期望值0,更新值10,更新值1
    • C A S更新
    • 如果期望值与lockValue值相等,则lockValue值更新为1,返回true,否则执行下面逻辑
    • 如果期望值与lockValue值不相等,不做任何更新,返回false

    C A S更新

    🎜🎜 🎜🎜🎜如果期望值与lockValue值相等,则lockValue值更新为1,返回

    Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

    Déclaration:
    Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer