c# - Problème CAS avec AtomicInteger
我想大声告诉你
我想大声告诉你 2017-06-28 09:24:31
0
1
775
 public final int incrementAndGet() {
        for (;;) {
            int current = get();
            int next = current + 1;
            if (compareAndSet(current, next))
                return next;
        }
    }

Il s'agit d'une opération d'auto-incrémentation, définition : CAS a 3 opérandes, une valeur mémoire V, une ancienne valeur attendue A et une nouvelle valeur à modifier B. Si et seulement si la valeur attendue A et la valeur mémoire V sont identiques, modifiez la valeur mémoire V en B, sinon ne faites rien
La valeur attendue est-elle la suivante ? La valeur de la mémoire est actuelle ?
S'il n'y a pas de concurrence d'autres threads lorsqu'un thread incrémente, alors la valeur attendue doit être supérieure de 1 à la valeur de la mémoire. Comment se fait-il que la valeur attendue et la valeur de la mémoire soient les mêmes ?

我想大声告诉你
我想大声告诉你

répondre à tous(1)
刘奇

Laxatif~
Peut-être que la compréhension de la question par l'auteur est un peu fausse

  1. current est la valeur attendue, pas la valeur de la mémoire

  2. suivant est la nouvelle valeur modifiée, pas la valeur attendue

Le code source de la

méthodecompareAndSet est visible et les commentaires à l'intérieur sont très clairs

/**
     * Atomically sets the value to the given updated value
     * if the current value {@code ==} the expected value.
     *
     * @param expect the expected value
     * @param update the new value
     * @return {@code true} if successful. False return indicates that
     * the actual value was not equal to the expected value.
     */
    public final boolean compareAndSet(int expect, int update) {
        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }

Le fonctionnement de CAS est comme mentionné par le sujet, en comparant la valeur attendue avec la valeur mémoire. Ce n'est que lorsqu'elles sont égales que la nouvelle valeur sera écrite, sinon elle sera réessayée en continu. C'est une attitude optimiste, et la vraie. valeur de la mémoire En fait, c'est une AtomicInteger.value这个属性(其实最关键也不是这个属性,只是个引用而已,真正的boss后面会提到),注意这个value的有关键字volatilemodification

private volatile int value;

Cette valeur est donc en fait une variable partagée, qui représente la visibilité de cette variable, c'est-à-dire la visibilité entre les threads,

======================== Je parle juste trop de visibilité, si vous ne l'aimez pas, vous pouvez simplement l'ignorer === ======== =====================

Pour faire simple, le modèle de mémoire Java stipule que les variables sont stockées dans la mémoire principale (similaire à la mémoire physique). Chaque thread possède son propre cache de travail. Lorsqu'on opère sur une variable, la valeur dans la mémoire principale n'est pas directement modifiée, mais il est exécuté dans son propre cache de travail, et finalement synchronisé avec la mémoire principale, et les threads ne peuvent pas accéder au cache de travail des autres

La visibilité mentionnée ici signifie que lorsqu'un thread exploite une variable modifiée avec le mot-clé volatile, lorsque la variable est modifiée et écrite avec succès dans la mémoire principale, les variables dans le cache de travail des autres threads deviendront invalides, donc lorsque d'autres threads relisez la variable, ils la liront directement depuis la mémoire principale au lieu d'utiliser la valeur dans leur propre cache de travail

==========================================Fini====== =========================================

Je viens de mentionner que l'attribut AtomicInteger.value n'est qu'une référence aux données elles-mêmes. Lors de l'appel de la méthode AtomicInteger.value这个属性对于数据本身而言,只是一个引用,在调用compareAndSet方法时,可以注意到第二个参数,valueOffset,其实这才是关键...真正的Boss,真正的内存的值,因为涉及到在java语言里很少听到的一个词,指针,这个valueOffset, vous pouvez remarquer le deuxième paramètre, valueOffset. , C'est la clé... le vrai Boss, la vraie valeur mémoire, car il s'agit d'un mot rarement entendu dans le langage Java, pointeur, ce valueOffset En fait, c'est le décalage au sein de l'objet. C'est la vraie valeur de la mémoire

.

(La raison pour laquelle cette méthode compareAndSet里调用的是Unsafe类的方法,Unsafe appelle la méthode de la classe Unsafe, Unsafe encapsule en fait certaines opérations de type pointeur, les pointeurs ne sont pas sûrs)

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!