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