web-dev-qa-db-fra.com

Quand dois-je utiliser AtomicBoolean en Java?

Comment puis-je utiliser AtomicBoolean et à quoi sert cette classe?

204
yart

Lorsque plusieurs threads doivent vérifier et changer le booléen. Par exemple:

if (!initialized) {
   initialize();
   initialized = true;
}

Ce n'est pas thread-safe. Vous pouvez le réparer en utilisant AtomicBoolean:

if (atomicInitialized.compareAndSet(false, true)) {
    initialize();
}
216
Bozho

Voici les notes (de livre de Brian Goetz ) que j'ai faites, cela pourrait vous aider

AtomicXXX classes

  • fournir une implémentation de comparaison et d'échange non bloquante

  • Tirant parti de la prise en charge fournie par le matériel (instruction CMPXCHG sur Intel) Lorsque de nombreux threads exécutant votre code utilisant cette API de concurrence simultanée, ils évoluent beaucoup mieux que le code utilisant des analyses/synchronisation au niveau de l’objet. Depuis, les mécanismes de synchronisation de Java font attendre le code. Lorsque de nombreux threads traversent vos sections critiques, le processeur consacre beaucoup de temps à la gestion du mécanisme de synchronisation lui-même (attente, notification, etc.). Étant donné que la nouvelle API utilise des constructions de niveau matériel (variables atomiques) et des algorithmes d’attente et de verrouillage pour implémenter la sécurité des threads, le processeur consacre plus de temps à la tâche à la tâche plutôt qu’à la gestion de la synchronisation.

  • non seulement ils offrent un meilleur débit, mais ils offrent également une plus grande résistance aux problèmes d’activité tels que l’impasse et l’inversion des priorités.

48
Aravind R. Yarram

Vous pouvez utiliser un booléen atomique pour deux raisons principales. D'abord son mutable, vous pouvez le passer comme référence et changer la valeur associée au booléen lui-même, par exemple.

public final class MyThreadSafeClass{

    private AtomicBoolean myBoolean = new AtomicBoolean(false);
    private SomeThreadSafeObject someObject = new SomeThreadSafeObject();

    public boolean doSomething(){
         someObject.doSomeWork(myBoolean);
         return myBoolean.get(); //will return true
    }
}

et dans la classe someObject

public final class SomeThreadSafeObject{
    public void doSomeWork(AtomicBoolean b){
        b.set(true);
    }
}

Plus important encore, son thread-safe et peut indiquer aux développeurs qui gèrent la classe que cette variable doit être modifiée et lue à partir de plusieurs threads. Si vous n'utilisez pas AtomicBoolean, vous devez synchroniser la variable booléenne que vous utilisez en la déclarant volatile ou en effectuant une synchronisation autour de la lecture et de l'écriture du champ.

33
John Vint

La classe AtomicBoolean vous donne une valeur booléenne que vous pouvez mettre à jour de manière atomique. Utilisez-le lorsque plusieurs threads accèdent à une variable booléenne.

La vue d'ensemble du paquet Java.util.concurrent.atomic vous donne une bonne description de haut niveau de ce que font les classes de ce paquet et du moment de leur utilisation. Je recommanderais également le livre Java Concurrency in Practice de Brian Goetz.

17
Cameron Skinner

Extrait du description du paquet

Paquet Description de Java.util.concurrent.atomic: Petite boîte à outils contenant des classes prenant en charge la programmation thread-safe sans verrou sur des variables simples. [...]

Les spécifications de ces méthodes permettent aux implémentations d'utiliser des instructions atomiques au niveau de la machine efficaces disponibles sur les processeurs modernes. [...]

Les instances des classes AtomicBoolean, AtomicInteger, AtomicLong et AtomicReference fournissent chacune un accès et des mises à jour à une seule variable du type correspondant. [...]

Les effets de mémoire pour les accès et les mises à jour d'atomics suivent généralement les règles pour les volatiles:

  • get a les effets de mémoire de la lecture d'une variable volatile.
  • set a les effets de mémoire d'écriture (assignation) d'une variable volatile.
  • faibleCompareAndSet lit et écrit de manière conditionnelle une variable, est ordonné par rapport aux autres opérations de mémoire sur cette variable, mais agit sinon comme une opération de mémoire non volatile ordinaire.
  • compareAndSet et toutes les autres opérations de lecture et de mise à jour telles que getAndIncrement ont les effets en mémoire des variables volatiles en lecture et en écriture.
5
OscarRyz