Cet article vous apporte une introduction au rôle de la classe atomique AtomicInteger (exemples de code). Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer. . aide.
Le rôle de la classe atomique AtomicInteger
Opération multithread, Synchronized a trop de surcharge de performances ++ n'est pas une opération atomique. Parce que count++ doit passer par trois étapes de lecture-modification-écriture.
count++ n'est pas une opération atomique. Parce que count++ doit passer par trois étapes de lecture-modification-écriture.
Vous pouvez faire ceci :
public synchronized void increase() { count++; }
Le verrouillage synchronisé est exclusif, ce qui signifie que si d'autres threads sont en cours d'exécution, le thread actuel ne peut qu'attendre !
Opération avec CAS
CAS a 3 opérandes :
Valeur mémoire V ancienne valeur attendue Une nouvelle valeur à modifier B lorsque plusieurs threads essaient Lorsque CAS est utilisé pour mettre à jour la même variable en même temps, un seul des threads peut mettre à jour la valeur de la variable (lorsque A et la valeur mémoire V sont identiques, modifier la valeur mémoire V en B), tandis que les autres threads échouent, et le le fil de discussion qui a échoué ne sera pas bloqué. Au lieu de cela, on vous dit que vous avez échoué au concours et que vous pouvez réessayer (ou ne rien faire).
Nous pouvons constater qu'il existe deux situations dans CAS :
Si la valeur de la mémoire V est égale à notre valeur attendue A, alors la valeur de la mémoire est modifiée en B et l'opération est réussie !
Si la valeur mémoire V n'est pas égale à notre valeur attendue A, il y a généralement deux situations :
Réessayer (tourner) et ne rien faire
Comprendre CAS Le noyau est :
CAS est atomique Bien que vous puissiez penser qu'il y a deux opérations après avoir vu la comparaison et la modification (comparer et échanger), c'est atomique après tout !
La classe de variables atomiques se trouve sous le package java.util.concurrent.atomic Dans l'ensemble, il existe tellement de
Types de base :
AtomicBoolean : Boolean AtomicInteger : Integer AtomicLong. : Type entier long
Tableau :
AtomicIntegerArray : Type entier dans le tableau AtomicLongArray : Type entier long dans le tableau AtomicReferenceArray : Type référence dans le tableau
Type de référence :
AtomicReference : Type de référence AtomicStampedReference : Type de référence avec numéro de version AtomicMarkableReference : Type de référence avec bits de marque
Propriétés de l'objet
AtomicIntegerFieldUpdater : Les propriétés de l'objet sont des entiers Type AtomicLongFieldUpdater : L'attribut de l'objet est un entier long AtomicReferenceFieldUpdater : L'attribut de l'objet est un type de référence
Le nouveau JDK8 DoubleAccumulator, LongAccumulator, DoubleAdder, LongAdder
est une amélioration d'AtomicLong et d'autres classes. Par exemple, LongAccumulator et LongAdder sont plus efficaces qu'AtomicLong dans les environnements à forte concurrence. Les classes du package Atomic sont essentiellement des classes wrapper implémentées à l'aide d'Unsafe
Il existe plusieurs méthodes (CAS) que nous aimons dans Unsafe :
// 第一和第二个参数代表对象的实例以及地址,第三个参数代表期望值,第四个参数代表更新值 public final native boolean compareAndSwapObject(Object var1, long var2, Object var4, Object var5); public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5); public final native boolean compareAndSwapLong(Object var1, long var2, long var4, long var6);
Les classes de variables atomiques utilisent
class Count{ // 共享变量(使用AtomicInteger来替代Synchronized锁) private AtomicInteger count = new AtomicInteger(0); public Integer getCount() { return count.get(); } public void increase() { count.incrementAndGet(); } }
Problème ABA atomique
Les opérations suivantes peuvent être effectuées normalement, mais quels problèmes surviendront ? ? Le thread C ne peut pas connaître les valeurs de comptage modifiées par le thread A et le thread B, ce qui est risqué.
Maintenant, j'ai une variable count=10. Maintenant, il y a trois threads, à savoir A, B, C. Le thread A et le thread C lisent la variable count en même temps, donc la valeur mémoire et la valeur attendue de thread A et thread C Les deux valent 10. À ce moment, le thread A utilise CAS pour modifier la valeur du compte à 100. Après la modification, à ce moment, le thread B entre et lit la valeur du compte comme 100 (la valeur de la mémoire et la valeur attendue est toutes deux 100) et change la valeur de comptage à 100. La valeur est modifiée à 10. Le thread C obtient le droit d'exécution et constate que la valeur de la mémoire est 10 et que la valeur attendue est également 10. Changez la valeur de comptage à 11
Résoudre le problème ABA
Pour résoudre le problème ABA, nous pouvons utiliser les classes AtomicStampedReference et AtomicMarkableReference fournies par le JDK.
Pour faire simple, il fournit une version pour cet objet, et si cette version est modifiée, elle sera automatiquement mise à jour.
Le principe est à peu près le suivant : un objet Pair est conservé, et l'objet Pair stocke notre référence d'objet et une valeur de tampon. Chaque fois que CAS compare deux objets Pair
LongAdder a de meilleures performances qu'AtomicLong
Lors de l'utilisation d'AtomicLong, un grand nombre de threads seront en compétition pour mettre à jour la même variable atomique en même temps dans une concurrence élevée, mais en raison du CAS simultané d'un seul thread réussira, donc d'autres threads continueront d'essayer de tourner et d'essayer des opérations CAS, ce qui gaspillera beaucoup de ressources CPU.
LongAdder peut être résumé comme suit : la valeur des données de base internes est séparée dans un tableau (Cell). Lorsque chaque thread y accède, elle est mappée à l'un des nombres pour le comptage via le hachage et d'autres algorithmes, et le résultat final du comptage est : c'est la somme et l'accumulation de ce tableau.
Pour faire simple, une valeur est dispersée en plusieurs valeurs, ce qui peut répartir la pression pendant la concurrence et améliorer les performances.
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!