2010-04-22 8 views
8

Oznaczanie zmiennej jako volatile w języku Java zapewnia, że ​​każdy wątek widzi wartość, która została do niego zapisana, zamiast jakiejś nieaktualnej wartości. Zastanawiałem się, jak to właściwie zostało osiągnięte. Czy JVM emituje specjalne instrukcje, które powodują opróżnienie procesora lub coś w tym stylu?Jak działa lotność?

+0

pytanie pokrewne (pierwszy na liście faktycznie ..) http://stackoverflow.com/questions/1787450/how-do- i-understand-read-memory-barriers-and-volatile – BalusC

+0

I wątek, który zacząłem na lotny z dużą ilością "upvotes" i "ulubionych" dotyczących wykonania poza kolejnością: http://stackoverflow.com/questions/2441279/java-volatile-gwarantuje-i-wykonanie-rzędu – SyntaxT3rr0r

Odpowiedz

8

Z tego co rozumiem, zawsze pojawia się tak, jakby pamięć podręczna została opróżniona po zapisaniu i zawsze pojawia się tak, jakby odczyty były wykonywane bezpośrednio z pamięci podczas odczytu. Efekt jest taki, że wątek zawsze będzie wyświetlał wyniki zapisów z innego wątku i (zgodnie z modelem pamięci Java) nigdy nie będzie wartością buforowaną. Rzeczywiste instrukcje implementacji i procesora różnią się jednak w zależności od architektury.

Nie gwarantuje poprawności, jeśli inkrementujesz zmienną w więcej niż jednym wątku, lub sprawdzasz jej wartość i podejmujesz pewne działania, ponieważ oczywiście nie ma faktycznej synchronizacji. Generalnie można zagwarantować tylko poprawne wykonanie, jeśli do zmiennej jest tylko zapis Wątku, a inne czytają.

Zauważ również, że 64-bitową zmienną NON-volatile można odczytać/zapisać jako dwie 32-bitowe zmienne, więc 32-bitowe zmienne są zapisane w trybie atomowym, ale 64-bitowe nie. Jedna połowa może być napisana przed inną - więc odczytana wartość może być mniejsza od starej lub nowej wartości.

Jest to dość pomocny strona z moich zakładek:

http://www.cs.umd.edu/~pugh/java/memoryModel/

+2

@jgubby: ostatni akapit nie wydaje się poprawny: nie można odczytać 64-bitowej zmiennej, która miałaby 32 bity z jednego zapisu, a druga 32 bity z innego zapisu. – SyntaxT3rr0r

+1

@WizardOfOdds: uzgodniono. Chciałbym tam powiedzieć zmienną nielotną. – gubby

+0

@jbuggy: ah ah, to właśnie myślałem, ale nie odważyłem się edytować twojego postu, ponieważ nie byłem pewien co masz na myśli :) Cieszę się, że pomogłem, bo w przeciwnym razie było to trochę mylące :))) – SyntaxT3rr0r

1

Dokładnie to, co się dzieje, zależy od procesora. Zasadniczo istnieją pewne instrukcje dotyczące barier pamięci. Opróżnianie całej pamięci podręcznej byłoby oczywiście bardzo kosztowne - w sprzęcie są protokoły koherencji pamięci podręcznej.

Ważne jest również to, że niektóre optymalizacje nie są wykonywane przez dostęp do pól. Kompilator jest ważny przy rozważaniu wielowątkowości, nie myśl tylko o sprzęcie.

+1

Dokładnie to, co dzieje się w poprawnie napisanym programie Java, nie jest specyficzne dla procesora. – gubby

+0

@jgubby Pytanie brzmi, czy emitowane są specjalne instrukcje. –