Volatile Vs Static w Javie

Czy poprawne jest twierdzenie, że static oznacza jedną kopię wartości dla wszystkich obiektów, a volatile oznacza jedną kopię wartości dla wszystkich wątków?

W każdym razie zmienna static będzie również jedną wartością dla wszystkich wątków, więc dlaczego powinniśmy wybrać volatile ?

Author: leppie, 2010-03-11

7 answers

Deklarowanie 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 Objects utworzonego w ogóle. Jednak wątki mogą mieć lokalnie buforowane wartości.

Gdy zmienna jest lotna , a nie statyczna , dla każdej Object będzie po jednej zmiennej. Tak więc, na powierzchni wydaje się, że nie ma różnicy od normalnej zmiennej, ale całkowicie różni się od static . Jednak nawet w przypadku pól Object wątek może buforować wartość zmiennej lokalnie.

Oznacza to, że jeśli dwa wątki aktualizują zmienną tego samego obiektu jednocześnie, a zmienna nie jest zadeklarowana jako zmienna 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 poprzez 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 static volatile i to zmusi wątek do odczytania za każdym razem wartości globalnej.

Jednak lotna nie jest substytutem prawidłowej synchronizacji!
Na przykład:

private static volatile int counter = 0;

private void concurrentMethodWrong() {
  counter = counter + 5;
  //do something
  counter = counter - 5;
}

Wykonywanie concurrentMethodWrong jednocześnie wiele razy może prowadzić do ostatecznej wartości licznika różnej od zera!
Aby rozwiązać problem, musisz zaimplementować blokadę:

private static final Object counterLock = new Object();

private static volatile int counter = 0;

private void concurrentMethodRight() {
  synchronized (counterLock) {
    counter = counter + 5;
  }
  //do something
  synchronized (counterLock) {
    counter = counter - 5;
  }
}

Lub użyć AtomicInteger klasy.

 331
Author: stivlo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-09 08:09:40

Różnica między statyczną i lotną :

Zmienna statyczna: Jeśli dwa wątki(przypuśćmy, że t1 i t2) uzyskują dostęp do tego samego obiektu i aktualizują zmienną zadeklarowaną jako statyczna, to oznacza to, że t1 i t2 mogą tworzyć własną lokalną kopię tego samego obiektu (łącznie ze zmiennymi statycznymi) w ich odpowiednim buforze, więc aktualizacja dokonana przez t1 do zmiennej statycznej w jej lokalnym buforze nie będzie odzwierciedlać w zmiennej statycznej dla bufora t2.

Static zmienne są używane w kontekście obiektu gdzie aktualizacja dokonana przez jeden obiekt będzie odzwierciedlać we wszystkich innych obiektach tej samej klasy , ale nie w kontekście wątku gdzie aktualizacja jednego wątku do zmiennej statycznej będzie odzwierciedlać zmiany natychmiast do wszystkich wątków (w ich lokalnej pamięci podręcznej).

Zmienna Volatile: Jeśli dwa wątki(Załóżmy, że t1 i t2) uzyskują dostęp do tego samego obiektu i aktualizują zmienną zadeklarowaną jako volatile, to oznacza to, że t1 i t2 mogą tworzyć własny lokalny bufor obiektu z wyjątkiem zmiennej zadeklarowanej jako zmienna. Tak więc zmienna lotna będzie miała tylko jedną główną kopię, która zostanie zaktualizowana przez różne wątki, a aktualizacja dokonana przez jeden wątek do zmiennej lotnej natychmiast odzwierciedli się w drugim wątku.

 277
Author: Som,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-25 12:51:41

Oprócz innych odpowiedzi, chciałbym dodać do niego jeden obrazek (zdjęcie ułatwia zrozumienie)

Tutaj wpisz opis obrazka

static zmienne mogą być buforowane dla poszczególnych wątków. W środowisku wielowątkowym jeśli jeden wątek modyfikuje dane w pamięci podręcznej, może to nie odzwierciedlać innych wątków, ponieważ mają one kopię.

volatile declaration upewnia się, że wątki nie będą buforować danych i używa tylko udostępnionej kopii.

Obraz źródło

 21
Author: mrsrinivas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-21 08:47:29

Myślę, że static i volatile nie mają żadnego związku. Proponuję przeczytać samouczek Javy, aby zrozumieć Atomic Access , i po co używać atomic access, zrozumieć co to jest interleaved , znajdziesz odpowiedź.

 5
Author: Amitābha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-30 23:35:17

W prostych słowach,

  1. Static : static zmienne są związane z Klasa, zamiast z jakąkolwiek obiekt. Każda instancja klasy dzieli zmienną klasy, która znajduje się w jednym stałym miejscu w pamięci

  2. Volatile : to słowo kluczowe dotyczy zarówno Klasa oraz instancja zmienne.

Używanie lotnych zmienne zmniejszają ryzyko błędów spójności pamięci, ponieważ każdy zapis do zmiennej zmiennej ustanawia relację happens-before z kolejnymi odczytami tej samej zmiennej. Oznacza to, że zmiany w zmiennej lotnej są zawsze widoczne dla innych wątków

Spójrz na ten Artykuł by Javin Paul aby lepiej zrozumieć zmienne lotne.

Tutaj wpisz opis obrazka

W przypadku braku słowa kluczowego volatile wartość zmiennej w każdym stos wątku może być inny. Zmieniając zmienną na volatile, wszystkie wątki otrzymają tę samą wartość w pamięci roboczej i uniknięto błędów spójności pamięci.

Tutaj termin {[4] } może być zmienną static (class) lub zmienną instance (object).

Odnośnie Twojego zapytania:

W każdym razie wartość zmiennej statycznej będzie również jedną wartością dla wszystkich wątków, więc dlaczego powinniśmy iść na volatile?

If I need instance variable in my aplikacji, nie mogę użyć zmiennej static. Nawet w przypadku zmiennej static, spójność nie jest gwarantowana ze względu na bufor wątków, jak pokazano na diagramie.

Użycie zmiennych volatile zmniejsza ryzyko błędów spójności pamięci, ponieważ każdy zapis do zmiennej zmiennej ustanawia relację happens-before z kolejnymi odczytami tej samej zmiennej. Oznacza to, że zmiany w zmiennej lotnej są zawsze widoczne dla innych wątków.

Co więcej, oznacza to również, że gdy wątek odczytuje zmienną zmienną, widzi nie tylko ostatnią zmianę zmiennej zmiennej, ale także skutki uboczne kodu, który doprowadził do tej zmiany => błędy spójności pamięci są nadal możliwe przy zmiennych zmiennych. Aby uniknąć skutków ubocznych, musisz użyć zmiennych zsynchronizowanych. Ale jest lepsze rozwiązanie w Javie.

Korzystanie z prostego dostępu do zmiennych atomowych jest bardziej wydajne niż dostęp do tych zmiennych poprzez zsynchronizowane kod

Niektóre z klas w pakiecie java.util.concurrent zapewniają metody atomowe, które nie polegają na synchronizacji.

Aby uzyskać więcej informacji, zapoznaj się z tym artykułem Kontrola współbieżności wysokiego poziomu.

Szczególnie spójrz na zmienne atomowe.

Podobne pytania SE:

Volatile Vs Atomic

Volatile boolean vs AtomicBoolean

Różnica między lotnym a synchronized in Java

 4
Author: Ravindra babu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:31:37

Zmienna zmienna zmienna dostęp będzie bezpośrednio z pamięci głównej. Powinien być stosowany tylko w środowisku wielowątkowym. zmienna statyczna zostanie załadowana jednorazowo. Jeśli jest używany w środowisku pojedynczego wątku, nawet jeśli kopia zmiennej zostanie zaktualizowana i nie będzie szkody dostęp do niej, ponieważ jest tylko jeden wątek.

Teraz, jeśli zmienna statyczna jest używana w środowisku wielowątkowym, to będą problemy, jeśli ktoś oczekuje od niej pożądanego rezultatu. Ponieważ każdy wątek ma swoją własną kopię wtedy każdy przyrost lub zmniejszenie zmiennej statycznej z jednego wątku może nie odzwierciedlać w innym wątku.

Jeśli ktoś oczekuje pożądanych wyników ze zmiennej statycznej, to użyj volatile z static w wielowątkowości, to wszystko zostanie rozwiązane.

 0
Author: Aslam anwer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-27 07:15:32

Jeśli zadeklarujemy zmienną jako statyczną, będzie tylko jedna kopia zmiennej. Tak więc, ilekroć różne wątki uzyskają dostęp do tej zmiennej, będzie tylko jedna końcowa wartość zmiennej (ponieważ jest tylko jedno miejsce pamięci przydzielone dla zmiennej).

Jeśli zmienna jest zadeklarowana jako zmienna zmienna, wszystkie wątki będą miały własną kopię zmiennej, ale wartość jest pobierana z głównego memory.So, wartość zmiennej we wszystkich wątkach będzie taka sama.

Więc w obu przypadki, głównym punktem jest to, że wartość zmiennej jest taka sama we wszystkich wątkach.

 -1
Author: Jitendra Nalwaya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-20 06:04:22