Czy jest jakaś różnica między volatile
odwołaniem do obiektu i AtomicReference
na wypadek, gdybym po prostu użył get()
i set()
-methods z AtomicReference
?
java
concurrency
auramo
źródło
źródło
Nie, nie ma.
Dodatkową mocą zapewnianą przez AtomicReference jest metoda compareAndSet () i przyjaciele. Jeśli nie potrzebujesz tych metod, zmienne odwołanie zapewnia taką samą semantykę jak AtomicReference.set () i .get ().
źródło
Istnieje kilka różnic i kompromisów:
Używanie
AtomicReference
get / set ma taką samą semantykę JMM jak zmienne pole (jak stwierdza javadoc), aleAtomicReference
jest opakowaniem wokół referencji, więc każdy dostęp do pola obejmuje dalszą pościg po wskaźnikach .Ilość pamięci jest mnożona (zakładając skompresowane środowisko OOP, co jest prawdą dla większości maszyn wirtualnych):
AtomicReference
= 4b + 16b (12b nagłówek obiektu + 4b pole odniesienia)AtomicReference
oferuje bogatsze API niż zmienne odniesienie. Możesz odzyskać API dla ulotnego odwołania, używając plikuAtomicFieldUpdater
, lub Java 9 aVarHandle
. Możesz też sięgnąć prosto,sun.misc.Unsafe
jeśli lubisz biegać z nożyczkami.AtomicReference
jest zaimplementowany przy użyciuUnsafe
.Kiedy więc dobrze jest wybrać jedną z nich:
AtomicReference
/AtomicFieldUpdater
/Unsafe
gdzie zwykle płacisz za czytelność i ryzyko wzrostu wydajności. Jeśli nie jest to wrażliwy obszar, po prostu idźAtomicReference
. Twórcy bibliotek zazwyczaj używają kombinacji tych metod w zależności od docelowych zestawów JDK, oczekiwanych ograniczeń interfejsu API, ograniczeń pamięci i tak dalej.źródło
Kod źródłowy JDK jest jednym z najlepszych sposobów odpowiedzi na takie niejasności. Jeśli spojrzysz na kod w AtomicReference, używa on zmiennej volatie do przechowywania obiektów.
Więc oczywiście, jeśli zamierzasz po prostu użyć get () i set () na AtomicReference, jest to jak użycie zmiennej lotnej. Ale jak skomentowali inni czytelnicy, AtomicReference zapewnia dodatkową semantykę CAS. Więc najpierw zdecyduj, czy chcesz semantyki CAS, czy nie, a jeśli tylko chcesz, użyj AtomicReference.
źródło
AtomicReference
zapewnia dodatkową funkcjonalność, której nie zapewnia zwykła zmienna zmienna. Po przeczytaniu Javadoc API będziesz o tym wiedział, ale zapewnia również blokadę, która może być przydatna w niektórych operacjach.Jeśli jednak nie potrzebujesz tej dodatkowej funkcjonalności, sugeruję użycie zwykłego
volatile
pola.źródło
volatile
Pola można używać jak każdego zwykłego pola, podczas gdy dostęp do wartości w anAtomicReference
wymaga przejściaget
iset
metod.Czasami, nawet jeśli używasz tylko pobierań i zestawów, AtomicReference może być dobrym wyborem:
Przykład z niestabilnym:
Implementacja z AtomicReference zapewniłaby bezpłatną synchronizację kopiowania przy zapisie.
Można by powiedzieć, że nadal możesz mieć odpowiednią kopię, jeśli zastąpisz:
z:
Jednak druga z nich jest bardziej prawdopodobna, że zostanie przypadkowo usunięta przez kogoś w przyszłości podczas „czyszczenia kodu”.
źródło