Quand dois-je utiliser AtomicBoolean en Java?

Comment puis-je utiliser AtomicBoolean et quelle est cette classe?

Lorsque plusieurs threads doivent vérifier et modifier 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(); } 

Voici les notes ( du livre de Brian Goetz) que j’ai faites qui pourraient vous être utiles

Classes AtomicXXX

  • fournir une implémentation de comparaison et d’échange sans blocage

  • Profite du support fourni par le matériel (l’instruction CMPXCHG sur Intel) Lorsque beaucoup de threads exécutent votre code qui utilise cette API de concomitance atomique, ils évolueront beaucoup mieux que le code qui utilise les moniteurs / synchronisations au niveau object. Étant donné que les mécanismes de synchronisation de Java font attendre le code, quand il y a beaucoup de threads dans vos sections critiques, une grande partie du temps processeur est consacrée à la gestion du mécanisme de synchronisation (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 locking pour implémenter la sécurité des threads, le temps de traitement est beaucoup plus important que la gestion de la synchronisation.

  • non seulement offrent un meilleur débit, mais ils offrent également une plus grande résistance aux problèmes de vivacité tels que les interblocages et les inversions de priorité.

Vous pouvez utiliser un booléen atomique pour deux raisons principales. Tout d’abord, il est possible de le transmettre en tant que référence et de modifier 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 est sûr 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 la synchronisant autour de la lecture et de l’écriture du champ.

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 présentation du package java.util.concurrent.atomic vous fournit une description de haut niveau de ce que font les classes de ce package et de leur utilisation. Je recommanderais également le livre Java Concurrency in Practice de Brian Goetz.

Extrait de la description du colis

Package java.util.concurrent.atomic description: Petit kit de classes prenant en charge la programmation thread-safe sans locking sur des variables uniques.

Les spécifications de ces méthodes permettent aux implémentations d’utiliser des instructions atomiques efficaces au niveau machine, disponibles sur les processeurs contemporains.

Les instances des classes AtomicBoolean, AtomicInteger, AtomicLong et AtomicReference fournissent chacune un access et des mises à jour à une variable unique du type correspondant. […]

Les effets de mémoire pour les access et les mises à jour d’atomes suivent généralement les règles pour les volatiles:

  • get a les effets mémoire de la lecture d’une variable volatile.
  • set a les effets mémoire d’écrire (assigner) une variable volatile.
  • faiblesseCompareAndSet lit et écrit de manière atomique une variable, est ordonnée par rapport aux autres opérations de mémoire sur cette variable, mais agit 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 de mémoire de lire et d’écrire des variables volatiles.