54 votes

booléen volatile vs AtomicBoolean

J'ai regardé les autres volatiles vs Atomicxxxx questions (y compris cette une) et avoir lu la description de java.util.actuel.atomique, et je ne suis pas tout à fait satisfait avec les nuances.

Si je suis en train de décider entre l'utilisation d' volatile boolean et AtomicBoolean, il y a des différences concrètes en plus de la atomique en lecture-modification-écriture opérations offertes par AtomicBoolean? (par exemple, compareAndSet() et getAndSet())

Supposons que j'ai

volatile boolean flag;

Ensuite, 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 - il adéquat?

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

  • l'espace mémoire
  • performances (volatile boolean semble exiger la mémoire de l'escrime, AtomicBoolean semble exiger la mémoire de l'escrime + quelques petites verrouillage sur le CAS des opérations conformément à la java.util.actuel.description atomique)

Mon intuition est un appel à aller juste avec AtomicBoolean et être en sécurité, mais je veux comprendre si il y a une situation d'utiliser des volatile boolean à la place (par exemple, si j'ai eu des milliers de cas d'eux et les performances ont été un problème).

72voto

biziclop Points 21446

La principale différence entre AtomicBoolean et volatile est que l'opération de comparaison et définition n'est pas atomique avec les variables volatile .

  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 concurrentes sont idempotentes et que vous ne lisez qu'un seul thread, cela ne devrait pas poser de problème.

19voto

Cowan Points 17235

Je ne suis pas sûr que je suis complètement d'accord avec les autres réponses ici; biziclop la réponse est juste comme il va, mais je ne suis pas sûr que nous pouvons en conclure que vous êtes en sécurité si nous ne savons plus en détail.

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 ce pourrait être bien (la deuxième série d' flag de true n'a pas d'importance, comme l' doStuff() sera encore probablement voir ce Thread 2 a besoin de faire.

Toutefois, si vous inversez l'ordre thread 3:

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

puis Thread 2 de la mise à jour pourrait être perdu.

Bien sûr, vous devez également être prudent avec ce que l'autre Thread 2 le fait, pour s'assurer qu'il est visible de Fil 3. Si il y a autre état que le Thread 2 doit définir, ordre devient important là aussi.

Dans le cas simple, oui, vous êtes bien, mais si elle devient plus complexe que la simple claquement des drapeaux ensuite, cela devient beaucoup plus difficile à raisonner.

18voto

Tom Hawtin - tackline Points 82671

Essentiellement, tous les AtomicBoolean sont des volatile boolean dans un objet.

Il y aura une petite surcharge par objet. Probablement insignifiant, mais peut-être plus de mémoire pour entrer dans le cache.

Si vous devez utiliser AtomicBooleanFieldUpdater il y a beaucoup de frais de performance. Cela peut être correct si vous n'allez pas le faire souvent (en tant que attach dans NIO).

7voto

snapfractalpop Points 573

Il y a beaucoup de bonnes informations ici. Cependant, j'ajouterais une autre différence qui pourrait être utile. Vous pouvez avoir un tableau d'AtomicBooleans mais vous ne pouvez pas (à ma connaissance) avoir un tableau de booléens volatils.

2voto

Sergey Tachenov Points 8123

Ensuite, un ou plusieurs threads définissent le drapeau (mais ne le désactivent pas). Si j'ai un thread qui lit l'indicateur, et si défini, une action, puis efface-t-elle l'indicateur, est-elle volatile?

Oui, si vous n’avez pas besoin des capacités spéciales d’AtomicBoolean, vous pouvez parfaitement utiliser volatile pour cette tâche. En fait, il s’agit de l’une des rares utilisations raisonnables des substances volatiles.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X