2011-08-12 16 views
5

To samo dla wszystkich innych obiektów atomowych? Łatwiej jest wyjaśnić pytanie AtomicInteger. Ponieważ więcej niż 1 wątek uzyskuje dostęp do odwołania do myInt, czy nie jest możliwe, że jeden wątek widzi zarejestrowaną wartość w pamięci podręcznej, na przykład null, dla tego obiektu, chyba że jest on również zadeklarowany jako niestabilny? Jeśli nie, to dlaczego?Czy konieczne jest zadeklarowanie AtomicReference jako zmiennej?

+0

Staram się, aby wszystkie pola AtomicReference były ostateczne. Powinieneś nigdy nie zmieniać tego. –

Odpowiedz

8

Nie tylko nie jest to konieczne, ale w rzeczywistości jest błędne semantycznie. AtomicReference przechowuje "rzeczywiste" odwołanie w sobie i zarządza dostępem do niego za pomocą własnych konstrukcji synchronizacji. Własne konstrukcje synchronizacji JVM (synchronized, , itp.) I nie są używane. Sam obiekt AtomicReference nie powinien być traktowany jako zmienny. Jeśli cokolwiek, rozważ zrobienie tego final.

Rozważ także this question - volatile może być uważana za alternatywę dla używania AtomicReference, jeśli wszystko czego potrzebujesz to operacje pobierania i ustawiania.

+0

Dlaczego nie? Współbieżna mapa mogłaby być trzymana przez zmienne pole z uzasadnionego powodu, i nie rozumiem, dlaczego nie powinno to być prawdą w przypadku "atomowych" obiektów? –

+0

@Nieno: Oczywiście, przypuszczam, że mógłbyś wymyślić scenariusz, w którym byłoby to właściwe. Jeśli jednak zobaczysz kod "volatile AtomicReference" w kodzie, prawie na pewno nie będzie to zgodne z zamierzeniami autora. – skaffman

+0

@skaffman: Oczywiście AtomicReferance zawiera prawdziwe odniesienie do obiektu docelowego w sobie, ale mam na myśli odniesienie do tego obiektu AtomicReference. Ale naprawdę mogę to uczynić ostatecznym i ma to również sens. Dzięki! –

1

Obiekty "atomowe" nie są niezmienne, więc powinny być bezpieczne tylko pod warunkiem, że zostaną poprawnie opublikowane. Na przykład, gdy zrobisz coś takiego, będziesz musiał użyć zmiennego słowa kluczowego.

volatile AtomicInteger counter = // initialize counter 

int harvest(){ 
    AtomicInteger old = counter; 
    counter = new AtomicInteger(); 
    return old.get(); 
} 

Jeśli usuniesz lotny z powyższego kodu, możesz rzeczywiście stracić kilka przyrostów. Zgodnie ze specyfikacją można również uzyskać odwołanie do obiektu AtomicInteger, który nie jest w pełni skonstruowany, a tym samym uzyskać niezdefiniowane zachowanie.

Czy należy zatem zadeklarować swój obiekt atomowy jako zmienny? Odpowiedź jest zależna. Są bezpieczne tylko tak długo, jak długo są poprawnie publikowane, tak jak inne bezpieczne obiekty (z wyjątkiem niezmiennych obiektów, które są przypadkami specjalnymi). W większości przypadków powinieneś zrobić je ostatecznym.

Powiązane problemy