Le principe d'implémentation sous-jacent de CAS dans la programmation concurrente Java

Qu'est-ce que CAS?

Le nom complet de CAS est Compare-And-Swap (l'implémentation interne du verrouillage optimiste)

Fonction: Utilisé pour juger si la valeur de valeur d'un certain emplacement dans la mémoire est la valeur attendue A, si c'est le cas, passez à la nouvelle valeur B, l'ensemble du processus d'opération est une opération atomique

scènes à utiliser:

CAS est incorporé dans le langage Java que les différentes méthodes de la classe sun.misc.Unsafe
appellent la méthode CAS dans la classe UnSafe. La JVM nous aidera à réaliser l'instruction d'assemblage CAS, qui dépend entièrement de la fonction matérielle, car CAS est une primitive système La primitive appartient à la catégorie du système d'exploitation. Elle est composée de plusieurs instructions pour terminer un processus d'une certaine fonction, et l'exécution de la primitive doit être continue, et elle ne doit pas être interrompue pendant l'exécution, ce qui signifie que CAS est Une instruction atomique CPU ne causera pas le soi-disant problème d'incohérence des données


À savoir: CAS est thread-safe

Attributs de base:

1. Classe de base non sécurisée

Étant donné que les méthodes Java ne peuvent pas accéder directement au système d'exploitation sous-jacent, elles doivent être accessibles via des méthodes natives. Unsafe équivaut à une porte dérobée, en fonction des données de mémoire spécifiques pouvant être directement manipulées. La classe Unsafe existe dans le package sun.misc et ses méthodes internes L'opération peut manipuler directement la mémoire comme le pointeur C

Étant donné que toutes les méthodes de la classe Unsafe sont modifiées de manière native, elles peuvent appeler directement les ressources sous-jacentes du système d'exploitation pour effectuer les tâches correspondantes. La raison pour laquelle la classe d'empaquetage Atomic modifiée peut garantir l'atomicité dépend de la classe unsafe sous-jacente.

2, variable valueOffset

Indique l'adresse de décalage de la valeur de variable dans la mémoire. Unsafe obtient les données en fonction de l'adresse de décalage de mémoire. Grâce à l'adresse de mémoire valueOffset, la valeur peut être obtenue directement, puis l'opération est ajoutée.

3. La valeur de la variable volatile modifiée

Assurer la visibilité de la mémoire entre plusieurs threads

Pendant le fonctionnement, vous devez comparer la valeur dans la mémoire d'opération et la comparer avec la valeur dans la mémoire principale

Si la comparaison de la valeur Value et de la valeur attendue A renvoie false, la méthode while est exécutée jusqu'à ce que la valeur attendue soit la même que la valeur de mémoire Value

Synchronized n'est pas utilisé dans la couche inférieure, mais CAS est utilisé pour améliorer l'accès concurrentiel et, en même temps, pour assurer la cohérence, car après que chaque thread arrive, il entre dans la boucle do while, puis obtient en permanence la valeur dans la mémoire. Il est nécessaire de juger si Est la dernière opération, puis mise à jour.

exemple:

假设线程A和线程B同时执行修改操作

1. value原始值为10,此时,线程A和线程B各自持有一份值为10的副本,分别存储在各自的工作内存
2. 当线程A拿到value值10的时候,CPU进行切换,线程A被挂起(失去CPU执行权)
3. 线程B也拿到Value值10,线程B并没有被挂起,接着执行了CAS方法,通过比较内存值正好为10,则表示成功,接着对内存值进行修改为15,至此,线程B修改操作完成
4. 之后线程A恢复,执行CAS方法,通过比较,发现自己副本获取到的值10和主内存中的数字15不一致,说明内存值已经被其它线程抢先一步修改,进而导致A线程本次修改失败,只能通过执行do while重新读取内存值后再进行CAS,因为内存值value被volatile修饰,所以其它线程对它的修改,线程A总能够看到,线程A继续执行compareAndSwapInt进行比较替换,直到成功。

Cela implique une idée de rotation, si l'opération retourne false, tournez jusqu'à ce que l'opération retourne true

Inconvénients du CAS

1. surcharge CPU élevée

     Si la concurrence est élevée, de nombreux threads doivent mettre à jour une variable et la mise à jour échoue plusieurs fois, et parce que CAS est une opération de rotation, des boucles répétées, entraînant un temps trop long, une consommation excessive et beaucoup de pression sur le processeur. Dans le pire des cas, la valeur obtenue par un thread est différente de la valeur attendue, donc il bouclera indéfiniment


2. CAS ne peut garantir que l'atomicité de niveau variable, pas l'atomicité des blocs de code

     Lors de l'exécution d'opérations sur une variable partagée, l'opération atomique peut être garantie en bouclant CAS, mais pour plusieurs opérations de variables partagées, la boucle CAS ne peut pas garantir l'atomicité de l'opération. Pour le moment, seuls les verrous peuvent être utilisés pour garantir l'atomicité.

 

3. Problème ABA
     CAS aura des problèmes ABA dans des scénarios multi-threads

   exemple:

线程A,期望值为10,欲更新的值为15
线程B,期望值为10,欲更新的值为15
     
场景:
    1.线程A抢先获得CPU时间片,而线程B因为其他原因阻塞
    2.线程A取值与期望的值10比较,发现相等然后将值更新为15
    3.这个时候出现了线程C,期望值为15,欲更新的值为10,线程C取值与期望的值15比较,发现相等则将值更新为10
    4.此时线程B从阻塞中恢复过来,并且获得了CPU时间片,这时候线程B取值与期望的值10比较,发现相等则将值更新为15
    虽然线程B也完成了操作,但是线程B并不知道这个值已经经过了10->15->10的变化过程。

 

    Solution:
    ajoutez le numéro de version devant la variable, le numéro de version de la variable est +1 à chaque mise à jour de la variable, c'est-à-dire que A-> B-> A devient 1A-> 2B-> 3A

Pour résumer:

CAS(compareAndSwap)

En comparant si la valeur actuelle de la mémoire de travail et la valeur de la mémoire physique principale sont égales, si elle renvoie true, effectuez l'opération spécifiée, retournez false, puis continuez la comparaison de rotation jusqu'à ce que les valeurs de la mémoire principale et de la mémoire de travail soient cohérentes

Je suppose que tu aimes

Origine blog.csdn.net/weixin_43562937/article/details/107180533
conseillé
Classement