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