2012-03-21 10 views
5

Czy ta klasa jest bezpieczna dla wątków?AtomicInteger vs synchronized getters/setters

Czy można wyświetlić niespójne wartości? Powiedzmy, że początkowo wartość a wynosi 80. Wątek 1 wywołuje setA(100) i wchodzi do funkcji, ale jeszcze nie zadzwonił pod numer a.set(100), a wątek 2 jednocześnie wywołuje getA(). Czy w wątku 2 można zobaczyć 80?

public class A { 
    private AtomicInteger a; 

    public int getA() { 
     return a.get() 
    } 

    public void setA(int newVal){ 
     a.set(newVal); 
    } 
} 

wiem, że synchronizacja będzie gwarantować wątek 2 100 widzi, ale nie wiem z AtomicInteger.

Odpowiedz

9

Czy ta klasa jest bezpieczna dla wątków?

Tak jest.

gwintu 1 wzywa Seta (100) i wchodzi do funkcji, ale jeszcze nie dzwonić a.set (100) i jednocześnie zwraca gwintu 2 Geta(). Czy w wątku 2 można zobaczyć 80?

Tak. Do czasu zakończenia kodu zapory, który synchronizuje zmienne pole wewnątrz AtomicInteger, warunki wyścigu mogą wynosić 80 lub 100.

Wątek 1 może nawet wejść w metodę AtomicInteger.set i znajdować się przed przypisaniem pola wewnętrznego, a mimo to 80 może zostać zwrócony metodą get: AtomicInteger.get.

Nie ma żadnych gwarancji dotyczących , gdy wartości zostaną zaktualizowane w innych wątkach. Gwarantowane jest, że po ukończeniu get() otrzymasz najnowszą zsynchronizowaną wartość, a gdy zakończy się set(), wszystkie pozostałe wątki zobaczą aktualizacje.

Nie ma gwarancji co do timingu wywoływania pobierającego i ustawiającego w różnych wątkach.

1

Jak zauważyła firma @Gray, istnieje tutaj warunek wyścigu.

Wywołanie get, a następnie set nie jest operacją atomową. The Atomic* classes oferuje bezproblemową operację aktualizacji warunkowej, compareAndSet - powinieneś użyć tej dla bezpieczeństwa wątków.

Powiązane problemy