8
votes

L'atomicité est-elle réalisée dans les classes définies dans Java.UtilL.ConCurrent.Atomic Package?

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;
    }
}


2 commentaires

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 . Dans un goto moins de langue, nous utilisons une boucle infinie.


3 Réponses :


7
votes

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.

Le but de ce code est de s'assurer que le champ volatile est mis à jour de manière appropriée sans la surcharge d'un synchronisé 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.

Le mot clé 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 volatile , 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 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 pour vous assurer que le volatile int est uniquement mis à jour à 4 (par exemple) s'il est toujours égal à 3 .

  1. T1 obtient l'atomique-int et il est 0.
  2. T2 obtient l'atomique-int et il est 0.
  3. t1 ajoute 1 à celui-ci
  4. t1 tests atomiquement pour vous assurer qu'il est 0, c'est et stocke 1.
  5. t2 ajoute 1 à celui-ci
  6. t2 tests atomiquement pour vous assurer qu'il est 0, il est pas , il doit donc tourner et réessayer.
  7. T2 obtient l'atomique-int et il est 1.
  8. t2 ajoute 1 à celui-ci
  9. t2 tests atomiquement pour vous assurer qu'il est 1, il est et stocke 2.

    Cela dessert-il un objectif particulier dans le modèle de mémoire Java (JMM).

    Non, il sert à des fins de la classe et des définitions de la méthode et utilise le JMM et les définitions de langue autour de volatile pour atteindre son objectif. Le JMM définit ce que fait la langue avec le synchronisé , volatile 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.

    Il s'agit de la méthode comparativité (...) au JMM en appelant dans la classe dangereuse qui est principalement des méthodes natales avec certains emballages: xxx


4 commentaires

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 est sur la visibilité; Atomicinteger est sur Atomicity sans verrouillage . Vous ne pouvez pas atteindre cela sans tentatives. LOOP INFINITE = TELETATIONS.


Eh bien volatile résout le problème de la visibilité sans utiliser le mot-clé synchronisé ne ne vous donne pas accès à un booléen.



6
votes

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.
}


1 commentaires

"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)



1
votes

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.

En cas d'incrémentation, nous lisons la valeur actuelle et appelez comparaissement comparatif (courant, actuel + 1) . 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.


0 commentaires