W książce Effective Java napisano:
Specyfikacja języka gwarantuje, że odczyt lub zapis zmiennej jest niepodzielny, chyba że zmienna jest typu
long
lubdouble
[JLS, 17.4.7].
Co oznacza „atomowy” w kontekście programowania Java lub programowania w ogóle?
volatile long
lubvolatile double
czyni atomowym zapis i atomowym.Odpowiedzi:
Oto przykład, ponieważ przykład jest często jaśniejszy niż długie wyjaśnienie. Załóżmy, że
foo
jest zmienną typulong
. Następująca operacja nie jest operacją atomową:Rzeczywiście, zmienna jest zapisywana za pomocą dwóch oddzielnych operacji: jednej, która zapisuje pierwsze 32 bity, i drugiej, która zapisuje ostatnie 32 bity. Oznacza to, że inny wątek może odczytać wartość
foo
i zobaczyć stan pośredni.Wykonanie operacji atomowej polega na użyciu mechanizmów synchronizacji, aby upewnić się, że operacja jest postrzegana, z dowolnego innego wątku, jako pojedyncza, atomowa (tj. Nierozdzielna na części) operacja. Oznacza to, że każdy inny wątek, po wykonaniu operacji atomowej, zobaczy albo wartość
foo
przed przypisaniem, albo po przypisaniu. Ale nigdy wartość pośrednia.Prostym sposobem na to jest uczynienie zmiennej zmienną :
Lub zsynchronizuj każdy dostęp do zmiennej:
Lub zastąpić go
AtomicLong
:źródło
„Operacja atomowa” oznacza operację, która wydaje się być natychmiastowa z perspektywy wszystkich innych wątków. Kiedy obowiązuje gwarancja, nie musisz się martwić o częściowo zakończoną operację.
źródło
Jest to coś, co „wydaje się reszcie systemu występować natychmiast” i mieści się w kategoryzacji liniowości w procesach obliczeniowych. Cytując dalej ten linkowany artykuł:
Na przykład w kontekście systemu bazy danych można mieć „zatwierdzenia atomowe”, co oznacza, że można przesłać zestaw zmian do relacyjnej bazy danych, a wszystkie zmiany zostaną albo przesłane, albo żadna z nich w ogóle w przypadku awarii, w ten sposób dane nie ulegają uszkodzeniu, aw następstwie blokad i / lub kolejek, następną operacją będzie inny zapis lub odczyt, ale dopiero po fakcie. W kontekście zmiennych i wątków jest tak samo w przypadku pamięci.
W cytacie podkreślono, że nie należy oczekiwać takiego zachowania we wszystkich przypadkach.
źródło
Właśnie znalazłem post Operacje atomowe vs. nieatomowe, które są dla mnie bardzo pomocne.
źródło
Jeśli masz kilka wątków wykonujących metody m1 i m2 w kodzie poniżej:
masz gwarancję, że każde wywołanie wątku
m2
będzie miało wartość 0 lub 5.Z drugiej strony za pomocą tego kodu (gdzie
i
jest długi):wywołanie wątku
m2
może odczytać 0, 1234567890L lub inną losową wartość, ponieważi = 1234567890L
nie można zagwarantować, że instrukcja jest niepodzielna dla along
(maszyna JVM może zapisać pierwsze 32 bity i ostatnie 32 bity w dwóch operacjach, a wątek może zaobserwowaći
pomiędzy nimi) .źródło
W Javie pola do odczytu i zapisu wszystkich typów oprócz długiego i podwójnego występują atomowo, a jeśli pole jest zadeklarowane zmiennym modyfikatorem, nawet długie i podwójne są atomowo odczytywane i zapisywane. Oznacza to, że otrzymujemy 100% tego, co tam było lub co się tam wydarzyło, ani nie może być żadnego pośredniego wyniku w zmiennych.
źródło