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 ?
Laxatif~
Peut-être que la compréhension de la question par l'auteur est un peu fausse
current est la valeur attendue, pas la valeur de la mémoire
suivant est la nouvelle valeur modifiée, pas la valeur attendue
méthode
compareAndSet
est visible et les commentaires à l'intérieur sont très clairsLe 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的有关键字volatile
modificationCette 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éthodeAtomicInteger.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, cevalueOffset
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 classeUnsafe
,Unsafe
encapsule en fait certaines opérations de type pointeur, les pointeurs ne sont pas sûrs)