Je traversais le code source de java.util.concurrent.atomic.atomicinteger i> Pour savoir comment atomicité est réalisée par les opérations atomiques fournies par la classe. Par exemple atomicinteger.getandinCrement () i> La source de méthode est la suivante public final int getAndIncrement() {
for (;;) {
int current = get();
int next = current + 1;
if (compareAndSet(current, next))
return current;
}
}
3 Réponses :
Je ne suis pas en mesure de comprendre le but d'écrire la séquence d'opérations à l'intérieur d'une boucle infinie. p>
Le but de ce code est de s'assurer que le champ
volatile code> est mis à jour de manière appropriée sans em> la surcharge d'un
synchronisé code> verrouillage. Sauf s'il y a un grand nombre de threads, tous en concurrence pour mettre à jour ce même domaine, cela va probablement tourner très peu de fois à atteindre cela. P>
Le mot clé code> Volatile fournit une visibilité et une mémoire. Synchronisation garantit mais ne garantit pas en elle-même les opérations atomiques avec plusieurs opérations (test et définie). Si vous testez, puis définissez un champ code> volatile code>, des conditions de raccordement si plusieurs threads tentent d'effectuer la même opération en même temps. Dans ce cas, si plusieurs threads tentent d'incrémenter le
atomicinteger code> en même temps, vous risquez de manquer l'un des incréments. Le code simultané utilisé ici utilise la boucle de spin et le
des méthodes sous-jacentes code> pour vous assurer que le
volatile int code> est uniquement mis à jour à 4 (par exemple) s'il est toujours égal à 3 . P>
- T1 obtient l'atomique-int et il est 0. Li>
- T2 obtient l'atomique-int et il est 0. li>
- t1 ajoute 1 à celui-ci li>
- t1 tests atomiquement em> pour vous assurer qu'il est 0, c'est et stocke 1. li>
- t2 ajoute 1 à celui-ci li>
- t2 tests atomiquement em> pour vous assurer qu'il est 0, il est pas em>, il doit donc tourner et réessayer. li>
- T2 obtient l'atomique-int et il est 1. Li>
- t2 ajoute 1 à celui-ci li>
- t2 tests atomiquement em> pour vous assurer qu'il est 1, il est em> et stocke 2. li> ol>
Cela dessert-il un objectif particulier dans le modèle de mémoire Java (JMM). P> BlockQuote>
Non, il sert à des fins de la classe et des définitions de la méthode et utilise em> le JMM et les définitions de langue autour de
volatile code> pour atteindre son objectif. Le JMM définit ce que fait la langue avec le
synchronisé code>,
volatile code> et d'autres mots-clés et comment plusieurs threads interagissent avec la mémoire mise en cache et centrale. Ceci est principalement sur les interactions indigènes de code avec le système d'exploitation et le matériel et est rarement, si jamais, sur le code Java. P>
Il s'agit de la méthode
comparativité (...) code> au JMM en appelant dans la classe
dangereuse code> qui est principalement des méthodes natales avec certains emballages: p>
xxx pré> blockQuote>
Selon ma compréhension de la volatilité: il résout le but de la visibilité sans utiliser de synchronisation ni de blocage explicite. Par conséquent, la volatilité peut être utilisée sans synchronisation pour une visibilité constante de lecture / écriture. Alors, pourquoi utiliser ce spécial pour la boucle pour la synchronisation? Si vous pouvez expliquer plus sur la relation entre les boucles et la synchronisation, ce serait une bonne aide. Merci pour une réponse instantanée.
@Vaibhavraj - La boucle n'a rien à voir avec la synchronisation. Il boucle jusqu'à ce que l'opération de CAS réussisse.
volatile code> est sur la visibilité;
Atomicinteger Code> est sur Atomicity sans verrouillage i>. Vous ne pouvez pas atteindre cela sans tentatives. LOOP INFINITE = TELETATIONS.
Eh bien volatile code> résout le problème de la visibilité sans utiliser le mot-clé code> synchronisé ", mais assurant la synchronisation de la mémoire fait partie de ce qu'il fait. Ce que ne i> ne vous donne pas accès à un booléen.
Je ne suis pas capable de comprendre le but d'écrire la séquence de opérations à l'intérieur d'un infini pour la boucle. P>
Comprendre pourquoi il est dans une boucle infinie, je trouve utile de comprendre ce que le compartiment
compareAreSet comment il peut renvoyer false. P>
volatile int count = 0; public int incrementAndGet(){ return ++count; //may return the same number more than once. }
"L'incrémentation n'est pas atomique" - car il s'agit essentiellement de 2 opérations, de lecture et d'écriture et des conditions de course peuvent toujours se produire entre ces opérations. Sauf si vous le faites atomique (littéralement = non séparable)
Le comparateur de Java est basé sur les instructions CPU Comparez-Swap (CAS) Voir http: //fr.wikipedia.org/wiki/compara-and-swap . Il compare le contenu d'un emplacement de mémoire à une valeur donnée et, seulement si elles sont identiques, modifie le contenu de cet emplacement de mémoire à une nouvelle valeur donnée. em> p>
En cas d'incrémentation, nous lisons la valeur actuelle et appelez comparaissement comparatif (courant, actuel + 1) code>. S'il renvoie False, cela signifie qu'un autre fil a interféré et modifié la valeur actuelle, ce qui signifie que notre tentative a échoué et que nous devons répéter tout le cycle jusqu'à ce qu'il réussisse. P>
Vous semblez ignorer qu'une méthode est appelée dans cette boucle et le résultat de cette méthode est la condition de briser la boucle. Google "comparer et échanger"
Ceci est un cas d'utilisation classique pour un
goto code>. Dans un
goto code> moins de langue, nous utilisons une boucle infinie.