Quand est-il préférable d'utiliser le booléen volatile dans Java plutôt qu'AtomicBoolean?

j'ai regardé les autres questions volatiles vs. Atomicxxxx dans SO (y compris celui-ci ) et ai lu la description de java.util.actuel.atomique , et je ne suis pas tout à fait satisfait des nuances.

si j'essaie de choisir entre volatile boolean et AtomicBoolean , y a-t-il des différences pratiques en dehors des opérations atomiques de lecture-modification-écriture offertes par AtomicBoolean? (par exemple compareAndSet() et getAndSet() )

supposez que j'ai

volatile boolean flag;

, Puis un ou plusieurs threads définir l'indicateur (mais pas supprimer). Si j'ai un thread qui lit le drapeau, et si, une action, puis efface le drapeau, est volatile adéquat?

Est-il un coût plus élevé pour AtomicBoolean que volatile de type boolean, en termes de

  • espace mémoire
  • performances ( volatile boolean semble nécessiter une clôture mémoire, AtomicBoolean semble nécessiter une clôture mémoire + un verrouillage mineur sur les opérations CAS selon le java.util.actuel.description atomique)

mon instinct est de simplement aller avec AtomicBoolean et être sûr, mais je veux comprendre s'il y a jamais une situation à utiliser volatile boolean à la place (par exemple si j'ai eu des milliers de cas d'eux et la performance était un problème).

48
demandé sur Community 2011-02-02 18:15:20

5 réponses

essentiellement toute AtomicBoolean est une volatile boolean dans un objet.

il y aura un petit overhead par objet. Probablement insignifiant, mais peut-être plus de mémoire pour entrer dans la cache.

si vous devez utiliser AtomicBooleanFieldUpdater alors il ya beaucoup de performances aériennes.Il peut être correct si vous n'allez pas le faire souvent (comme attach dans NIO).

15
répondu Tom Hawtin - tackline 2014-09-17 13:31:36

la principale différence entre AtomicBoolean et volatile d'un point de vue pratique est que l'opération de comparaison-et-ensemble n'est pas atomique avec volatile variables.

 volatile boolean b;

 void foo() {
   if( b ) {
     //Here another thread might have already changed the value of b to false
     b = false;
   }
 }

mais vu que toutes vos Écritures simultanées sont idempotent et que vous ne lisez qu'à partir d'un seul fil, cela ne devrait pas poser de problème.

64
répondu biziclop 2011-02-02 16:21:45

Je ne suis pas sûr que je suis entièrement d'accord avec les autres réponses ici; la réponse de biziclop est juste en ce qui concerne cela, mais je ne suis pas sûr que nous pouvons conclure que vous êtes en sécurité à moins que nous savons plus de détails.

Dans le cas simple, l'entrelacement pourrait ressembler à ceci:

Thread 1 (writer)   Thread 2 (Writer)  Thread 3 (Reader)
-----------------   -----------------  -----------------
flag = true;
                                       if (flag) {
                    flag = true;
                                         flag = false;
                                         doStuff();

et cela pourrait être très bien (la deuxième série de flag à true n'a pas d'importance, car doStuff() verra probablement encore ce que le fil 2 doit faire.

cependant si vous inversez le thread d'ordre 3 fait:

Thread 1 (writer)   Thread 2 (Writer)  Thread 3 (Reader)
-----------------   -----------------  -----------------
flag = true;
                                       if (flag) {
                                         doStuff();
                    flag = true;
                                         flag = false;

alors la mise à jour de Thread 2 pourrait être perdue.

bien sûr, vous devez être également prudent avec tout ce que Thread 2 fait D'autre, pour s'assurer qu'il est visible à Thread 3. S'il y a un autre État que Thread 2 doit régler, l'ordre devient important là aussi.

dans le cas simple, oui, vous allez bien, mais si cela devient plus complexe que de simples claquements de drapeaux ensuite, cela devient beaucoup plus difficile à raisonner.

19
répondu Cowan 2011-02-02 23:46:02

Il y a beaucoup de bonnes informations ici. Toutefois, je voudrais ajouter une autre différence qui pourrait être utile. Vous pouvez avoir une rangée de booléens atomiques, mais vous ne pouvez pas (à ma connaissance) avoir une rangée de booléens volatils.

6
répondu snapfractalpop 2012-10-03 13:44:30

ensuite, un ou plusieurs fils placent le drapeau (mais pas supprimer). Si j'en ai un fil qui lit le drapeau, et si ensemble, une action, puis efface le drapeau est-il volatile?

Oui, si vous n'avez pas besoin de compétences spéciales de AtomicBoolean, c'est très bien d'utiliser volatile pour cela. En fait, il s'agit de l'une des rares utilisations raisonnables de volatiles.

2
répondu Sergei Tachenov 2011-02-02 15:38:17