Czy słusznie jest powiedzieć, że static
oznacza to jedną kopię wartości dla wszystkich obiektów ivolatile
oznacza jedną kopię wartości dla wszystkich wątków?
W każdym razie static
wartość zmiennej będzie również jedną wartością dla wszystkich wątków, więc po co mamy iść volatile
?
Odpowiedzi:
Zadeklarowanie zmiennej statycznej w Javie oznacza, że będzie tylko jedna kopia, bez względu na to, ile obiektów klasy zostanie utworzonych. Zmienna będzie dostępna nawet bez jej
Objects
utworzenia. Jednak wątki mogą mieć lokalnie buforowane wartości.Kiedy zmienna jest lotna i niestatyczna , dla każdej będzie jedna zmienna
Object
. Na powierzchni wydaje się więc, że nie ma różnicy od normalnej zmiennej, ale całkowicie różni się od statycznej . Jednak nawet w przypadkuObject
pól wątek może buforować lokalnie wartość zmiennej.Oznacza to, że jeśli dwa wątki aktualizują jednocześnie zmienną tego samego obiektu, a zmienna nie jest deklarowana jako zmienna, może wystąpić przypadek, w którym jeden z wątków ma w pamięci podręcznej starą wartość.
Nawet jeśli uzyskasz dostęp do wartości statycznej przez wiele wątków, każdy wątek może mieć swoją lokalną kopię w pamięci podręcznej! Aby tego uniknąć, możesz zadeklarować zmienną jako niestabilną statycznie, co zmusi wątek do odczytu za każdym razem, gdy wartość globalna.
Jednakże lotny nie jest substytutem dla właściwej synchronizacji!
Na przykład:
Wykonywanie
concurrentMethodWrong
równolegle wiele razy może doprowadzić do końcowej wartości licznika różnej od zera!Aby rozwiązać problem, musisz wprowadzić blokadę:
Lub skorzystaj z
AtomicInteger
klasy.źródło
Różnica między statycznym a lotnym:
Zmienna statyczna : Jeśli dwa wątki (przypuśćmy
t1
it2
) uzyskują dostęp do tego samego obiektu i aktualizują zmienną zadeklarowaną jako statyczną, oznacza tot1
it2
może tworzyć własną lokalną kopię tego samego obiektu (w tym zmiennych statycznych) w odpowiedniej pamięci podręcznej, więc zaktualizuj wykonane przezt1
zmienną statyczną w lokalnej pamięci podręcznej nie będzie odzwierciedlać zmiennej statycznej dlat2
pamięci podręcznej.Zmienne statyczne są używane w kontekście Object, gdzie aktualizacja dokonana przez jeden obiekt odzwierciedlałaby wszystkie inne obiekty tej samej klasy, ale nie w kontekście Thread gdzie aktualizacja jednego wątku do zmiennej statycznej natychmiast odzwierciedla zmiany we wszystkich wątki (w lokalnej pamięci podręcznej).
Zmienna zmienna : jeśli dwa Wątki (przypuśćmy
t1
it2
) uzyskują dostęp do tego samego obiektu i aktualizują zmienną, która jest zadeklarowana jako zmienna, oznacza tot1
it2
może utworzyć własną lokalną pamięć podręczną obiektu, z wyjątkiem zmiennej, która jest zadeklarowana jako zmienna . Zatem zmienna zmienna będzie miała tylko jedną kopię główną, która zostanie zaktualizowana przez różne wątki, a aktualizacja dokonana przez jeden wątek do zmiennej niestabilnej zostanie natychmiast odzwierciedlona w drugim wątku.źródło
volatile
zmienna może być współużytkowana przez różne pamięci podręczne procesorów. Nie stanowi to problemu, ponieważ pamięć podręczna negocjuje wyłączną własność linii pamięci podręcznej przed jej modyfikacją.Oprócz innych odpowiedzi chciałbym dodać dla niego jedno zdjęcie (zdjęcie jest łatwe do zrozumienia)
static
zmienne mogą być buforowane dla poszczególnych wątków. W środowisku wielowątkowym, jeśli jeden wątek modyfikuje swoje buforowane dane, może to nie odzwierciedlać innych wątków, ponieważ mają ich kopię .volatile
deklaracja zapewnia, że wątki nie buforują danych i używa tylko kopii udostępnionej .Źródło obrazu
źródło
Myślę
static
ivolatile
wcale nie mam związku. Sugeruję przeczytanie samouczka Java, aby zrozumieć dostęp atomowy i dlaczego korzystać z dostępu atomowego, zrozumieć, co jest przeplatane , znajdziesz odpowiedź.źródło
W prostych słowach,
static :
static
zmienne są powiązane z klasą , a nie z dowolnym obiektem . Każde wystąpienie klasy dzieli zmienną klasy, która znajduje się w jednym ustalonym miejscu w pamięcilotny : to słowo kluczowe dotyczy zarówno zmiennych klas, jak i instancji .
Przeczytaj ten artykuł ,
Javin Paul
aby lepiej zrozumieć zmienne zmienne.W przypadku braku
volatile
słowa kluczowego wartość zmiennej w stosie każdego wątku może być inna. Dokonując zmiennej jakovolatile
wszystkie wątki otrzymają tę samą wartość w pamięci roboczej i uniknięto błędów spójności pamięci.Tutaj termin
variable
może byćstatic
zmienną (klasową) lubinstance
(obiektową).Jeśli chodzi o zapytanie:
Jeśli potrzebuję
instance
zmiennej w mojej aplikacji, nie mogę użyćstatic
zmiennej. Nawet w przypadkustatic
zmiennej spójność nie jest gwarantowana ze względu na pamięć podręczną wątków, jak pokazano na schemacie.Korzystanie ze
volatile
zmiennych zmniejsza ryzyko błędów spójności pamięci, ponieważ każdy zapis do zmiennej lotnej ustanawia relację przed zdarzeniem z kolejnymi odczytami tej samej zmiennej. Oznacza to, że zmiany zmiennej lotnej są zawsze widoczne dla innych wątków.Korzystanie z prostego dostępu do zmiennych atomowych jest bardziej wydajne niż uzyskiwanie dostępu do tych zmiennych za pomocą zsynchronizowanego kodu
Niektóre klasy w
java.util.concurrent
pakiecie udostępniają metody atomowe, które nie polegają na synchronizacji.Więcej informacji można znaleźć w tym artykule dotyczącym kontroli współbieżności na wysokim poziomie .
W szczególności spójrz na zmienne atomowe .
Powiązane pytania SE:
Volatile Vs Atomic
Volatile boolean vs AtomicBoolean
Różnica między zmienną i zsynchronizowaną w Javie
źródło
volatile
wcześniej, ale odpowiedź ta wyjaśnia wiele dla mnie dlaczego wciąż muszą korzystaćvolatile
zestatic
zmiennej.dostęp do zmiennej wartości będzie bezpośredni z pamięci głównej. Powinien być używany tylko w środowisku wielowątkowym. zmienna statyczna zostanie załadowana jeden raz. Jeśli jest używany w środowisku jednowątkowym, nawet jeśli kopia zmiennej zostanie zaktualizowana i dostęp do niej nie zaszkodzi, ponieważ istnieje tylko jeden wątek.
Teraz, jeśli zmienna statyczna jest używana w środowisku wielowątkowym, pojawią się problemy, jeśli oczekuje się od niej pożądanego wyniku. Ponieważ każdy wątek ma swoją własną kopię, jakiekolwiek zwiększenie lub zmniejszenie zmiennej statycznej z jednego wątku może nie odzwierciedlać innego wątku.
jeśli oczekuje się pożądanych wyników od zmiennej statycznej, to użyj zmiennej lotnej ze statyczną w wielowątkowości, wtedy wszystko zostanie rozwiązane.
źródło
Nie jestem pewien, czy zmienne statyczne są buforowane w lokalnej pamięci wątku, czy NIE. Ale kiedy wykonałem dwa wątki (T1, T2) uzyskując dostęp do tego samego obiektu (obj) i kiedy aktualizacja dokonana przez wątek T1 do zmiennej statycznej została odzwierciedlona w T2.
źródło
Jeśli zadeklarujemy zmienną jako statyczną, będzie tylko jedna kopia zmiennej. Tak więc, ilekroć różne wątki uzyskują dostęp do tej zmiennej, będzie tylko jedna końcowa wartość dla zmiennej (ponieważ dla zmiennej przypisana jest tylko jedna lokalizacja pamięci).
Jeśli zmienna zostanie zadeklarowana jako niestabilna, wszystkie wątki będą miały własną kopię zmiennej, ale wartość zostanie pobrana z pamięci głównej, więc wartość zmiennej we wszystkich wątkach będzie taka sama.
Tak więc w obu przypadkach głównym punktem jest to, że wartość zmiennej jest taka sama we wszystkich wątkach.
źródło