2012-04-02 24 views
6

jestem trochę zdezorientowany ...Jakie operacje są operacje atomowe

Czy to prawda, że ​​czytanie \ piśmie z kilku nitek wszystko z wyjątkiem długości i podwójne są operacje atomowe i to trzeba użyć lotny tylko długa i podwoi?

+1

Czy masz źródło dla tego? – paislee

Odpowiedz

8

Wygląda na to, że masz na myśli this section JLS. Jest gwarantowany dla wszystkich typów pierwotnych - z wyjątkiem double i long - że wszystkie wątki zobaczą pewną wartość, która została faktycznie zapisana w tej zmiennej. (W przypadku double i long pierwsze cztery bajty mogły zostać zapisane przez jeden wątek, a ostatnie cztery bajty przez inny wątek, jak określono w tej sekcji JLS.) Ale niekoniecznie zobaczą one wartość o wartości w w tym samym czasie, chyba że zmienna jest oznaczona volatile.

Nawet przy użyciu volatile, x += 3 nie jest atomowy, bo to x = x + 3, która robi się czytać i pisać, a tam może być zapisuje x między odczytu i zapisu. Dlatego mamy takie rzeczy jak AtomicInteger i inne narzędzia w java.util.concurrent.

0

To nie brzmi dobrze.

Operacja atomowa to taka, która zmusza wszystkie wątki do oczekiwania na dostęp do zasobu, dopóki nie zostanie zrobiony inny wątek. Nie rozumiem, dlaczego inne typy danych miałyby charakter atomowy, a inne nie.

3

Nie mylić atomowych z wątkami bezpiecznymi. Długie i podwójne zapisy nie są atomowe pod spodem, ponieważ każdy z nich składa się z dwóch oddzielnych 32-bitowych sklepów. Przechowywanie i ładowanie pól nie długich/podwójnych jest idealnie atomowe, zakładając, że nie są to zapisy złożone (na przykład: i++).

Według atomisty, nie będziesz czytać jakiegoś zniekształconego obiektu w wyniku wielu wątków piszących różne obiekty na tym samym polu.

Od Java Concurrency In Practice 3.1.2

Out-of-cienka-Aire bezpieczeństwa: Gdy wątek czyta zmienną bez synchronizacji, może zobaczyć wartość nieświeże, ale przynajmniej widzi, że wartość został umieszczony tam przez jakiś wątek, a nie jako wartość losowa. Dotyczy to wszystkich zmiennych, z wyjątkiem 64-bitowej długości i podwójnej, które nie są niestabilne. JVM może traktować 64-bitowe odczytywanie lub zapisywanie jako dwie oddzielne operacje 32-bitowe, które nie są atomowe.

0

lotny ma inne semantykę niż tylko pisanie wartość atomowo

oznacza to, że inne wątki mogą natychmiast zobaczyć zaktualizowaną wartość (i że nie może być zoptymalizowana out)