2016-08-09 14 views
5

Jako klasa Integer jest również niezmienna klasa i wiemy, że niezmienna klasa jest wątkowo bezpieczne, co jest potrzebą Atomowej Integer. Jestem zdezorientowany. Jest to powód, dla którego odczytywanie i zapisywanie niezmiennych obiektów nie musi być atomowe, podczas gdy odczytywanie i zapisywanie całkowitej liczby atomowej jest atomowe. Oznacza to, że klasy atomowe są również bezpieczne dla wątków.Jaka jest różnica między klasą całkowitą Atomic Integer i Normal immutable Integer w Javie?

+0

której klasy używać, gdy? – user18424

+3

Cóż, jeden jest zmienny, drugi niezmienny. Więc * możesz * używać 'AtomicInteger' kiedy potrzebujesz zmiennej wartości (inne opcje istnieją), nie możesz użyć' Integer'. –

+1

Możesz użyć 'AtomicInteger', gdy potrzebujesz ** wartości bezpiecznej ** wartości zmiennej, a nie tylko zmiennej wartości ... – Eduen

Odpowiedz

0

Rozważmy zmienną

int myInt = 3; 

AtomicInteger dotyczy myInt.

Integer odnosi się do 3.

innymi słowy, zmienna jest zmienna i może zmieniać jej wartość. Podczas gdy wartość 3 jest całkowitą literalną, stałą, niezmienną ekspresją.

Liczby całkowite są obiektowymi reprezentacjami literałów i dlatego są niezmienne, można je w zasadzie tylko przeczytać.

AtomicIntegers to kontenery dla tych wartości. Możesz je czytać i ustawiać. Taki sam jak przypisywanie wartości do zmiennej. Ale różne od zmiany wartości zmiennej int, operacje na AtomicInteger są atomowe.

Na przykład nie jest atomowy

if(myInt == 3) { 
    myInt++; 
} 

To jest atomowy

AtomicInteger myInt = new AtomicInteger(3); 

//atomic 
myInt.compareAndSet(3, 4); 
+0

Podczas gdy ta odpowiedź wydaje się zawierać ogólny jej sens, 'AtomicInteger' nie może odnosić się do zmiennej' int', więc twój przykład na pierwszych 3 liniach jest po prostu mylący. – Kayaman

+0

Przepraszam, nie jestem native speakerem, nie mam na myśli odniesienia jak w "odniesienie do java", ale bardziej w znaczeniu "mleko odnosi się do krowy jak whool odnosi się do owiec", ale może "odesłanie" nie jest właściwym słowem w tym przypadek, "relacja" byłaby lepsza? –

+0

Tak, dużo jaśniej. – Kayaman

2

Podczas gdy obiekty są niezmienne wątku bezpieczny z definicji Zmienne obiekty może być zbyt bezpieczne wątku.

Taki jest właśnie cel klas Atomic... (AtomicInteger, AtomicBoolean itd.).

Różne metody ...get... i ...set... umożliwiają bezpieczny dostęp do wątku i mutację obiektu.

Nie jest niespodzianką, że klasa jest zadeklarowana w pakiecie java.util.concurrent.

Trzeba tylko przeglądać API dla pakietu java.util.concurrent.atomic:

małych narzędzi klas obsługujących wątek bezpieczne programowanie blokady darmo na pojedynczych zmiennych.

+0

Klasa atomowa powinna mieć lepszą wydajność niż niezmienne klasy wrapperów, myślę, że – user18424

+3

@ user18424 Ponieważ tak naprawdę nie możesz ich używać w tym samym celu, myślisz źle. Nie ma logicznego sposobu na porównanie wydajności między tymi dwiema klasami. – Kayaman

+0

@ user18424 niezupełnie. W kontekście pojedynczego wątku, chcesz trzymać się "Liczba" faktycznie. Wszystko zależy od użycia. – Mena

0

AtomicInteger jest wątek bezpieczne (w rzeczywistości, wszystkie klasy z pakietu java.util.concurrent.atomic są bezpieczne dla wątków), podczas gdy normalne całkowitymi NIE są threadsafe.

Ty wymagałoby „zsynchronizowane” & „lotne” słowa kluczowe, kiedy używasz zmiennej wykonania „Integer” w środowisku wielowątkowym (aby to bezpieczeństwo wątków), gdzie podobnie jak w przypadku liczb atomowych nie trzeba „zsynchronizowane "&" zmienne "słowa kluczowe jako liczby całkowite atomowe dbają o bezpieczeństwo wątków.

Również polecam poniżej pomocny poradnik na ten sam temat: http://tutorials.jenkov.com/java-concurrency/compare-and-swap.html

Patrz poniżej oracle doc Więcej informacji na temat „atomowej” pakietu: https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/package-summary.html

+0

Normalna klasa Integer jest niezmienna, która jest również bezpieczna dla wątków. – user18424

+0

Normal Integer jest bezpieczna dla wątków tylko wtedy, gdy używasz słów kluczowych "zsynchronizowanych" i "niestabilnych". – developer

+0

@developer Integer jest niezmienny i dlatego domyślnie jest wątkowo bezpieczny, nie wymaga synchronizacji ani niestabilności. Jednak wadą niezmienności jest to, że wartość nigdy się nie zmienia. Jeśli potrzebujesz zmiennej wartości, użyj AtomicInteger lub innej metody lub niestabilnych/zsynchronizowanych słów kluczowych. – puhlen

2

AtomicInteger jest używany w środowiskach wielowątkowych kiedy musisz się upewnić, że tylko jeden wątek może zaktualizować zmienną int. Zaletą jest to, że żadna zewnętrzna synchronizacja nie jest wymagana, ponieważ operacje, które modyfikują jej wartość, są wykonywane w sposób bezpieczny dla wątków.

Rozważmy kod followind:

private int count; 

public int updateCounter() { 
    return ++count; 
} 

Jeżeli wiele wątków będzie wywołać metodę updateCounter, to możliwe, że niektóre z nich otrzyma taką samą wartość. Powód, dla którego operacja count ++ nie jest atomowa, jest nie tylko jedną operacją, ale wykonaną z trzech operacji: read count, add 1 to it's value and write it back to it. W wielu wątkach wywołania zmienna może być niezmodyfikowana do najnowszej wartości.

Powyższy kod powinien być zastąpione w tym:

private AtomicInteger count = new AtomicInteger(0); 
public int updateCounter() { 
    return count.incrementAndGet(); 
} 

Sposób incrementAndGet gwarantuje atomowo przyrost przechowywaną wartość i jest wartością powrotu bez użycia synchonization zewnętrznej.

Jeśli twoja wartość nigdy się nie zmienia, nie musisz używać AtomicInteger, wystarczy użyć int.

Powiązane problemy