Czy jest jakaś różnica między odniesienia volatile
obiekt i AtomicReference
w razie chciałbym po prostu wykorzystać get()
i set()
-methods z AtomicReference
?Java lotnych odniesienia vs. AtomicReference
Odpowiedz
Krótka odpowiedź brzmi: Nie
Z java.util.concurrent.atomic package doc:
Efekty pamięci dla dostępów i aktualizacji atomistyki ogólnie przestrzegać zasady lotne:
get
ma pamięć efekty odczytu zmiennejvolatile
.set
ma pamięć efektów pisania (przypisywania) zmiennejvolatile
.
Nawiasem mówiąc, doc dla pakietu jest bardzo dobra i wszystko jest wyjaśnione ...
lazySet
(wprowadzony w Javie 6) jest nowsza operacja wprowadzona że ma semantykę nieosiągalne poprzez zmienne volatile
; Aby uzyskać więcej informacji, patrz this post.
Nie, nie ma.
Dodatkowa moc dostarczana przez AtomicReference to metoda compareAndSet() i przyjaciele. Jeśli nie potrzebujesz tych metod, zmienne odniesienie zapewnia tę samą semantykę, co AtomicReference.set() i .get().
AtomicReference zapewnia dodatkową funkcjonalność, której nie zapewnia zwykła zmienna lotna. Jak już czytałeś API, wiesz o tym, ale zapewnia również blokadę, która może być przydatna w niektórych operacjach.
Jednakże, jeśli nie potrzebujesz tej dodatkowej funkcjonalności, sugeruję użycie zwykłego pola zmiennego.
Różnica polega na tym, że ich występ. Gdyby nie było różnicy, nigdy byś nie sugerował używania jednej z drugiej. –
Wydajność jest bardzo podobna. AtomicRefrence zwiększa złożoność i zużycie pamięci. –
@BT Pole 'volatile' może być używane jak zwykłe pole, podczas gdy dostęp do wartości w' AtomicReference' wymaga przechodzenia przez metody 'get' i' set'. –
JDK source code jest jednym z najlepszych sposobów na odpowiedź na konfuzje takie jak ta. Jeśli spojrzysz na kod w AtomicReference, używa zmiennej volatie do przechowywania obiektów.
private volatile V value;
Tak, oczywiście, jeśli masz zamiar po prostu użyć get() i set() na AtomicReference to jest jak za pomocą zmiennej zmienne. Ale, jak skomentowali inni czytelnicy, AtomicReference zapewnia dodatkową semantykę CAS. Tak więc, najpierw zdecyduj, czy chcesz semantyki CAS, czy nie, a jeśli robisz to tylko wtedy użyj AtomicReference.
* "Kod źródłowy JDK jest jednym z najlepszych sposobów na odpowiedź na takie konfuzje" * => Niekoniecznie się zgadzam - javadoc (który jest kontraktem klasy) jest najlepszym sposobem. To, co znajdziesz w kodzie, odpowiada na pytanie o konkretną implementację, ale kod może się zmienić. – assylias
Na przykład [this variable] (http://stackoverflow.com/a/14363501/829571) w hashmap był niestabilny w JDK 6, ale nie jest już niestabilny w Javie 7. Czy oparłeś swój kod na fakcie, że zmienna był niestabilny, zepsułby się podczas tłumaczenia JDK ... Co prawda przykład jest inny, ale masz rację. – assylias
Istnieje kilka różnic i kompromisów:
Korzystanie się
AtomicReference
get/zestaw ma taką samą JMM semantykę jako pole lotnej (jako stanów javadoc), aleAtomicReference
jest owinięcie wokół odniesienie, więc każdy dostęp do pola obejmuje kolejny wskaźnik pościgu.Ślad pamięci mnoży (zakładając środowiska ups skompresowane, co ma miejsce w przypadku większości maszyn wirtualnych):
- lotny ref = 4b
AtomicReference
= 4b + 16b (obiektu 12b nagłówek + Pole 4b ref)
AtomicReference
oferuje bogatszy interfejs API niż ulotne odniesienie. Możesz odzyskać API dla ulotnego odniesienia za pomocąAtomicFieldUpdater
lub z Java 9 aVarHandle
. Możesz także sięgnąć prosto dosun.misc.Unsafe
, jeśli lubisz biegać z nożyczkami.AtomicReference
samo zaimplementowane przy użyciuUnsafe
.
Więc, kiedy jest dobrze, aby wybrać jeden nad drugim:
- wystarczy get/set? Trzymaj się z lotnym polem, najprostszym rozwiązaniem i najniższym obciążeniem.
- Potrzebujesz dodatkowej funkcjonalności? Jeśli jest to wydajność (obciążenie związane z szybkością/pamięcią), czuła część twojego kodu dokonuje wyboru między
AtomicReference
/AtomicFieldUpdater
/Unsafe
, gdzie zazwyczaj płacisz w czytelności i ryzyku wzrostu wydajności. Jeśli nie jest to obszar wrażliwy, po prostu przejdź naAtomicReference
. Autorzy bibliotek zwykle używają kombinacji tych metod w zależności od wybranych JDK, oczekiwanych ograniczeń API, ograniczeń pamięci i tak dalej.
- 1. AtomicReference in Java - niezbędne do ustawienia odniesienia w środowisku bezpiecznym dla wątków?
- 2. Jaka jest różnica między AtomicReference <Integer> vs. AtomicInteger?
- 3. Java statyczne samo-odniesienia
- 4. leniwe inicjowanie bez synchronizacji lub lotnych hasła
- 5. Jak używać lotnych na Kotlin
- 6. dlaczego używasz lotnych z zsynchronizowanym blokiem?
- 7. RCPP przechodzą przez vs. odniesienia o wartości
- 8. odniesienia nazw w C# vs. VB.Net
- 9. Jak używać lotnych poprawnie w Javie
- 10. Czy konieczne jest zadeklarowanie AtomicReference jako zmiennej?
- 11. test słaby odniesienia przed użyciem Java
- 12. Jak działają odniesienia konstruktora tablic Java 8?
- 13. Lista Java vs ArrayList
- 14. java: Class.isInstance vs Class.isAssignableFrom
- 15. Logowanie Java vs Log4J
- 16. Java: ArrayBlockingQueue vs. LinkedBlockingQueue
- 17. Java JRE vs GCJ
- 18. Java: LockSupport.parkNanos vs Thread.Sleep (...)
- 19. Java Thread.stop() vs Thread.interrupt()
- 20. Java CachedThreadPool vs FixedThreadPool
- 21. Java: CopyOnWriteArrayList vs synchronizedList
- 22. Metody Java vs. funkcje
- 23. Struts vs Zend? Java vs PHP?
- 24. Czy wątek AtomicReference java jest bezpieczny podczas używania w ramach parallelStream?
- 25. Java 8 performance VS. Java 7
- 26. VS 2013 Znajdź wszystkie odniesienia nie działa w Pages cshtml
- 27. C# Podania typ odniesienia bezpośrednio vs parametr out
- 28. dynamiczny const pole vs. dowolnym stare pole odniesienia zachowania const
- 29. Przypisanie do niestanowiącego odniesienia odniesienia
- 30. Klasa vs pakiet vs moduł vs komponent vs kontener kontra serwis vs platforma w świecie Java
A dłuższa odpowiedź byłaby? –
Uzgodnione. Potrzebujemy przynajmniej łącza. –
Link do dłuższej odpowiedzi: http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/atomic/package-summary.html –