Kiedy lepiej używać volatile boolean w Javie niż AtomicBoolean?

Spojrzałem na inne pytania volatile vs. Atomicxxxx w SO (w tym to ) i przeczytałem Opis Javy.util.aktualne.atomic, i nie jestem do końca zadowolony z niuansów.

Jeśli próbuję zdecydować między użyciem volatile boolean i AtomicBoolean, Czy istnieją praktyczne różnice poza atomicboolean operacjami odczytu-modyfikacji-zapisu? (np. compareAndSet() i getAndSet())

Przypuśćmy, że mam

volatile boolean flag;

Następnie jeden lub więcej wątków ustawionych flaga (ale jej nie wyczyściła). Jeśli mam jeden wątek, który odczytuje flagę i jeśli jest ustawiony, czy akcja, a następnie czyści flagę, jest volatile odpowiednia?

AtomicBoolean jest jedną z najbardziej popularnych platform w Europie.]}
  • przestrzeń pamięci
  • performance hit (volatile boolean wydaje się wymagać szermierki pamięci, AtomicBoolean wydaje się wymagać szermierki pamięci + Niewielkiego blokowania operacji CAS zgodnie z Javą.util.aktualne.opis atomowy)

Mój instynkt to po prostu wybierz AtomicBoolean i bądź bezpieczny, ale chcę zrozumieć, czy istnieje kiedykolwiek sytuacja, aby użyć volatile boolean zamiast (np. gdybym miał tysiące ich wystąpień i wydajność były problemem).

Author: Community, 2011-02-02

5 answers

W zasadzie wszystko AtomicBoolean jest volatile boolean w obiekcie.

Będzie mały narzut na obiekt. Prawdopodobnie nieistotne, ale prawdopodobnie więcej pamięci, aby dostać się do pamięci podręcznej.

Jeśli potrzebujesz użyć AtomicBooleanFieldUpdater to jest całkiem spora wydajność overhead.It może być w porządku, jeśli nie będziesz robił tego często (jak attach W NIO).

 15
Author: Tom Hawtin - tackline,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-17 13:31:36

Główna różnica między AtomicBoolean i volatile z praktycznego punktu widzenia jest taka, że operacja compare-and-set nie jest atomowa ze zmiennymi volatile.

 volatile boolean b;

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

Ale ponieważ wszystkie Twoje równoczesne zapisy są idempotentne i czytasz tylko z jednego wątku, nie powinno to być problemem.

 64
Author: biziclop,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-02 16:21:45

Nie jestem pewien, czy całkowicie zgadzam się z innymi odpowiedziami tutaj; odpowiedź biziclopa jest poprawna, o ile idzie, ale nie jestem pewien, czy możemy stwierdzić, że jesteś bezpieczny, chyba że znamy więcej szczegółów.

W prostym przypadku przeplatanie może wyglądać tak:

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

I to może być w porządku (drugi zestaw flag do true nie ma znaczenia, ponieważ doStuff() nadal prawdopodobnie zobaczy, co trzeba zrobić w wątku 2.

Jednak jeśli odwrócisz kolejność wątku 3 robi:

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

Wtedy Aktualizacja wątku 2 może zostać utracona.

Oczywiście musisz być równie ostrożny z tym, co robi wątek 2, aby upewnić się, że jest widoczny dla wątku 3. Jeśli istnieje inny stan, który wątek 2 musi ustawić, porządek również tam staje się ważny.

W prostym przypadku, tak, jesteś w porządku, ale jeśli staje się to bardziej skomplikowane niż zwykłe machanie flagami, to staje się o wiele trudniejsze do rozumowania.

 19
Author: Cowan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-02 23:46:02

Jest tu wiele dobrych informacji. Chciałbym jednak dodać kolejną różnicę, która może być przydatna. Możesz mieć tablicę Atomicbooleanów, ale nie możesz (według mojej wiedzy) mieć tablicy lotnych booleanów.

 6
Author: snapfractalpop,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-03 13:44:30

Następnie jeden lub więcej wątków ustawia flagę (ale nie jasne). If I have one wątek, który odczytuje flagę, a jeśli Ustaw, wykonuje akcję, a następnie czyści flaga, czy lotna jest odpowiednia?

Tak, jeśli nie potrzebujesz specjalnych zdolności AtomicBoolean, możesz użyć volatile. W rzeczywistości jest to jeden z niewielu rozsądnych zastosowań lotnych.

 2
Author: Sergei Tachenov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-02 15:38:17