Czy kiedykolwiek używałeś słowa kluczowego volatile w Javie?

Dzisiaj w pracy natknąłem się na volatile słowo kluczowe w Javie. Nie będąc bardzo zaznajomionym z tym, znalazłem to Wyjaśnienie:

Java teoria i praktyka: Zarządzanie zmiennością

Biorąc pod uwagę szczegóły, w których ten artykuł wyjaśnia słowo kluczowe, o którym mowa, czy kiedykolwiek go używasz lub czy kiedykolwiek widzisz przypadek, w którym możesz użyć tego słowa kluczowego we właściwy sposób?

Author: Daniel Werner, 2008-09-20

21 answers

volatile posiada semantykę widoczności pamięci. Zasadniczo, wartość pola volatile staje się widoczna dla wszystkich czytelników (w szczególności dla innych wątków) po zakończeniu operacji zapisu na nim. Bez volatile czytelnicy mogli zobaczyć jakąś nie zaktualizowaną wartość.

Aby odpowiedzieć na twoje pytanie: tak, używam zmiennej volatile, aby kontrolować, czy jakiś kod kontynuuje pętlę. Pętla testuje wartość volatile i kontynuuje, jeśli jest to true. Warunek można ustawić na false przez wywołanie metody "stop". Pętla widzi false i kończy się, gdy testuje wartość po zakończeniu wykonywania metody stop.

Książka "współbieżność Javy w praktyce", którą gorąco polecam, daje dobre wyjaśnienie volatile. Ta książka jest napisana przez tę samą osobę, która napisała artykuł IBM, o którym mowa w pytaniu (w rzeczywistości cytuje swoją książkę na dole tego artykułu). Moje użycie volatile jest tym, co jego artykuł nazywa " flagą statusu wzorca 1."

Jeśli chcesz dowiedzieć się więcej o tym, jak volatile Działa pod maską, czytaj na model pamięci Java . Jeśli chcesz wyjść poza ten poziom, sprawdź dobrą książkę o architekturze komputera, taką jak Hennessy & Patterson i przeczytaj o spójności pamięci podręcznej i spójności pamięci podręcznej.

 632
Author: Greg Mattes,
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-11 07:44:40

"... modyfikator Lotny gwarantuje, że każdy wątek, który czyta pole, zobaczy ostatnio zapisaną wartość." - Josh Bloch

Jeśli myślisz o użyciu volatile, przeczytaj na opakowaniu java.util.concurrent która zajmuje się atomowym zachowaniem.

Post Wikipedii na Singleton wzór pokazuje Lotne W UŻYCIU.

 148
Author: Andrew Turner,
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-11 07:43:16

Ważny punkt o volatile:

  1. synchronizacja w Javie jest możliwa poprzez użycie słów kluczowych Java synchronized i volatile oraz zamków.
  2. w Javie nie możemy mieć zmiennej synchronized. Użycie słowa kluczowego synchronized ze zmienną jest nielegalne i spowoduje błąd kompilacji. Zamiast używać zmiennej synchronized w języku Java, możesz użyć zmiennej java volatile, która poinstruuje wątki JVM, aby odczytały wartość zmiennej volatile z pamięci głównej i nie buforowały jej lokalnie.
  3. jeśli zmienna nie jest współdzielona między wieloma wątkami, nie ma potrzeby używania słowa kluczowego volatile.

Źródło

Przykładowe zastosowanie volatile:

public class Singleton {
    private static volatile Singleton _instance; // volatile variable
    public static Singleton getInstance() {
        if (_instance == null) {
            synchronized (Singleton.class) {
                if (_instance == null)
                    _instance = new Singleton();
            }
        }
        return _instance;
    }
}

Tworzymy instancję leniwie w momencie, gdy pojawia się pierwsze żądanie.

Jeśli nie stworzymy zmiennej _instance volatile wtedy wątek, który tworzy instancję Singleton, nie będzie w stanie komunikować się z innym wątkiem. Więc jeśli wątek A tworzy Singleton instancja i zaraz po utworzeniu procesor ulega uszkodzeniu itp., wszystkie inne wątki nie będą w stanie zobaczyć wartości _instance jako not null i uwierzą, że nadal jest przypisana null.

Dlaczego tak się dzieje? Ponieważ wątki reader nie blokują i dopóki wątek writer nie wyjdzie z zsynchronizowanego bloku, pamięć nie zostanie zsynchronizowana, a wartość _instance nie zostanie zaktualizowana w pamięci głównej. Ze słowem kluczowym Volatile w Javie, jest to obsługiwane przez samą Javę i takie aktualizacje będą widoczne dla wszystkich wątków czytnika.

Wniosek: volatile Słowo kluczowe jest również używane do przekazywania zawartości pamięci między wątkami.

Przykładowe użycie bez lotnych:

public class Singleton{    
    private static Singleton _instance;   //without volatile variable
    public static Singleton getInstance(){   
          if(_instance == null){  
              synchronized(Singleton.class){  
               if(_instance == null) _instance = new Singleton(); 
      } 
     }   
    return _instance;  
    }

Powyższy kod nie jest bezpieczny dla wątków. Chociaż sprawdza wartość instancji ponownie w ramach bloku synchronizowanego (ze względu na wydajność), kompilator JIT może zmienić bajt kodu w taki sposób, że odniesienie do instancji jest ustawiane przed zakończeniem wykonywania przez konstruktora. Oznacza to, że metoda getInstance () zwraca obiekt, który nie został w pełni zainicjowany. Aby zabezpieczyć wątek kodu, od wersji Java 5 można użyć słowa kluczowego volatile dla zmiennej instancji. Zmienne, które są oznaczone jako lotne, są widoczne dla innych wątków dopiero po całkowitym zakończeniu wykonywania przez konstruktora obiektu.
źródło

Tutaj wpisz opis obrazka

volatile zastosowanie w Java :

Iteratory fail-fast są zazwyczaj zaimplementowane przy użyciu licznika volatile na obiekcie list.
  • gdy lista jest aktualizowana, licznik jest zwiększany.
  • kiedy tworzony jest Iterator, bieżąca wartość licznika jest osadzana w obiekcie Iterator.
  • gdy wykonywana jest operacja Iterator, metoda porównuje dwie wartości licznika i rzuca ConcurrentModificationException, jeśli są różne.

Implementacja fail-safe Iteratory są zazwyczaj lekkie. Zazwyczaj opierają się one na właściwościach struktur danych konkretnej implementacji listy. Nie ma ogólnego wzoru.

 83
Author: Premraj,
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-06-26 15:45:27

Volatile jest bardzo przydatny do zatrzymywania wątków.

Nie to, że powinieneś pisać własne wątki, Java 1.6 ma wiele ładnych puli wątków. Ale jeśli jesteś pewien, że potrzebujesz wątku, musisz wiedzieć, jak go zatrzymać.

Wzór, którego używam dla wątków to:

public class Foo extends Thread {
  private volatile boolean close = false;
  public void run() {
    while(!close) {
      // do work
    }
  }
  public void close() {
    close = true;
    // interrupt here if needed
  }
}

Zauważ, że nie ma potrzeby synchronizacji

 44
Author: Pyrolistical,
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
2008-09-24 22:29:39

Jednym z powszechnych przykładów użycia volatile jest użycie zmiennej volatile boolean jako znacznika do zakończenia wątku. Jeśli rozpocząłeś wątek i chcesz mieć możliwość bezpiecznego przerwania go z innego wątku, możesz okresowo sprawdzać flagę wątku. Aby to powstrzymać, Ustaw flagę na true. Wykonując flagę volatile, możesz mieć pewność, że sprawdzający ją wątek zobaczy, że została ustawiona przy następnym sprawdzaniu bez konieczności używania bloku synchronized.

 28
Author: Dave L.,
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
2008-09-20 04:00:01

Tak, zmienna musi być używana, gdy chcesz, aby zmienna była dostępna dla wielu wątków. Nie jest to bardzo powszechne użycie, ponieważ zazwyczaj musisz wykonać więcej niż jedną operację atomową (np. sprawdzić stan zmiennej przed jej modyfikacją), w którym to przypadku zamiast tego użyjesz zsynchronizowanego bloku.

 12
Author: ykaganovich,
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
2008-09-20 04:26:30

Nikt nie wspomniał o traktowaniu operacji odczytu i zapisu dla typu zmiennej długiej i podwójnej. Odczyty i zapisy są operacjami atomowymi dla zmiennych referencyjnych i dla większości prymitywnych zmiennych, z wyjątkiem długich i podwójnych typów zmiennych, które muszą używać słowa kluczowego volatile, aby być operacjami atomowymi. @ link

 12
Author: Donatello Boccaforno,
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-11 14:51:29

IMO dwa ważne scenariusze poza zatrzymaniem wątku, w którym używane jest słowo kluczowe volatile to

  1. Podwójnie sprawdzony mechanizm blokujący . Często używane w Singleton design wzór. W tym singleton object needs to be declared volatile.
  2. Fałszywe Pobudki . Wątek może czasami obudzić się z połączenia oczekującego, nawet jeśli nie zostało wydane żadne powiadomienie. To zachowanie nazywa się supurious wakeup. Można temu przeciwdziałać za pomocą zmiennej warunkowej(znacznik boolean). Umieść wywołanie wait () w pętli while jako dopóki flaga jest prawdziwa. Więc jeśli wątek obudzi się z połączenia oczekującego z przyczyn innych niż notify / notifyall to napotka flagę jest nadal prawdziwa, a tym samym wywołuje ponownie wait. Przed wywołaniem notify ustaw tę flagę na true. W tym przypadku boolean flag is declared as volatile.
 9
Author: Aniket Thakur,
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
2014-02-25 09:17:27

Zmienna zadeklarowana za pomocą słowa kluczowego volatile, ma dwie główne cechy, które czynią ją wyjątkową.

  1. Jeśli mamy zmienną zmienną, nie można jej buforować w pamięci podręcznej komputera(mikroprocesora) przez dowolny wątek. Dostęp zawsze odbywał się z pamięci głównej.

  2. Jeśli istnieje operacja zapisu dzieje się zmienna zmienna, i nagle operacja odczytu jest wymagane, gwarantuje się, że operacja zapisu zostanie zakończona przed operacją odczytu.

Dwie powyższe cechy dedukują, że

  • wszystkie wątki czytające zmienną lotną z pewnością odczytają najnowszą wartość. Ponieważ żadna wartość buforowana nie może jej zanieczyścić. A także żądanie odczytu zostanie udzielone dopiero po zakończeniu bieżącej operacji zapisu.

I z drugiej strony

  • jeśli dalej zbadamy #2 o czym wspomniałem, widzimy, że volatile słowo kluczowe jest idealnym sposobem na utrzymanie współdzielonej zmiennej, która ma 'n' Liczba wątków do odczytu i tylko jeden wątek do zapisu aby uzyskać do niego dostęp. Po dodaniu słowa kluczowego volatile jest to zrobione. Nie ma żadnych innych napowietrznych na temat bezpieczeństwa nici.

We can ' t używać wyłącznie słowa kluczowego volatile, aby zaspokoić współdzieloną zmienną, która ma więcej niż jeden wątek zapisu.

 8
Author: Supun Wijerathne,
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-06-23 02:28:48

Musisz użyć słowa kluczowego "volatile" lub "synchronized" oraz wszelkich innych narzędzi i technik kontroli współbieżności, które możesz mieć do dyspozycji, jeśli tworzysz wielowątkową aplikację. Przykładem takiej aplikacji są aplikacje desktopowe.

Jeśli tworzysz aplikację, która zostanie wdrożona na serwerze aplikacji (Tomcat, JBoss AS, Glassfish, itp.), nie musisz samodzielnie obsługiwać kontroli współbieżności, ponieważ jest ona już zaadresowana przez serwer aplikacji. W rzeczywistości, jeśli poprawnie zapamiętany standard Java EE zakazuje jakiejkolwiek kontroli współbieżności w servletach i EJB, ponieważ jest częścią warstwy "infrastructure", która powinna być wolna od obsługi. Sterowanie współbieżnością odbywa się w takiej aplikacji tylko wtedy, gdy implementujesz obiekty singleton. To nawet już rozwiązane, jeśli dzianiny swoje komponenty za pomocą frameworkd jak wiosna.

Tak więc w większości przypadków Java development gdzie aplikacja jest aplikacją webową i używa frameworka IOC takiego jak Spring lub EJB, nie musiałbyś używać "lotnych".

 5
Author: Rudi Adianto,
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
2012-07-10 18:02:44

volatile tylko gwarantuje, że wszystkie wątki, nawet same, są incrementing. Na przykład: licznik widzi tę samą powierzchnię zmiennej w tym samym czasie. Nie jest używany zamiast zsynchronizowanych lub atomowych lub innych rzeczy, całkowicie sprawia, że odczyty są zsynchronizowane. Nie porównuj go z innymi słowami kluczowymi java. Jak pokazuje poniższy przykład lotne operacje zmiennych są również atomowe, które nie powiodą się lub od razu odniosą sukces.

package io.netty.example.telnet;

import java.util.ArrayList;
import java.util.List;

public class Main {

    public static volatile  int a = 0;
    public static void main(String args[]) throws InterruptedException{

        List<Thread> list = new  ArrayList<Thread>();
        for(int i = 0 ; i<11 ;i++){
            list.add(new Pojo());
        }

        for (Thread thread : list) {
            thread.start();
        }

        Thread.sleep(20000);
        System.out.println(a);
    }
}
class Pojo extends Thread{
    int a = 10001;
    public void run() {
        while(a-->0){
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Main.a++;
            System.out.println("a = "+Main.a);
        }
    }
}

Nawet jeśli umieścisz lotne lub nie Wyniki zawsze będą się różnić. Ale jeśli używasz AtomicInteger jak poniżej wyniki będą zawsze takie same. Tak samo jest z synchronizowane również.

    package io.netty.example.telnet;

    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.atomic.AtomicInteger;

    public class Main {

        public static volatile  AtomicInteger a = new AtomicInteger(0);
        public static void main(String args[]) throws InterruptedException{

            List<Thread> list = new  ArrayList<Thread>();
            for(int i = 0 ; i<11 ;i++){
                list.add(new Pojo());
            }

            for (Thread thread : list) {
                thread.start();
            }

            Thread.sleep(20000);
            System.out.println(a.get());

        }
    }
    class Pojo extends Thread{
        int a = 10001;
        public void run() {
            while(a-->0){
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                Main.a.incrementAndGet();
                System.out.println("a = "+Main.a);
            }
        }
    }
 5
Author: fatih tekin,
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-08-18 15:06:14

Tak, używam go dość często - może być bardzo przydatny dla kodu wielowątkowego. Artykuł, na który wskazałeś, jest dobry. Chociaż są dwie ważne rzeczy, o których należy pamiętać:

  1. Należy używać lotnych tylko wtedy, gdy całkowicie zrozumieć, co to robi i czym się różni synchronizacja. W wielu sytuacjach pojawia się, na powierzchni, aby być prostszym bardziej wykonująca alternatywa dla zsynchronizowane, gdy często lepiej rozumienie lotności uczyniłoby jasne, że synchronized is the only opcja, która by zadziałała.
  2. Lotny nie działa w dużo starszych JVM, chociaż zsynchronizowane. Pamiętam, że widziałem dokument, który odnosił się do różnych poziomów wsparcia w różnych JVMs, ale niestety nie mogę go teraz znaleźć. Zdecydowanie przyjrzyj się temu, jeśli używasz Java pre 1.5 lub jeśli nie masz kontroli nad JVMs, na którym będzie działał Twój program.
 4
Author: MB.,
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
2008-09-20 11:07:48

Oczywiście, tak. (I to nie tylko w Javie, ale także w C#.) Są chwile, kiedy musisz uzyskać lub ustawić wartość, która jest gwarantowana jako operacja atomowa na danej platformie, na przykład int lub boolean, ale nie wymagają narzutu blokowania gwintu. Słowo kluczowe volatile pozwala upewnić się, że podczas odczytu wartości otrzymujesz current wartość, a nie wartość buforowaną, która została przestarzała przez zapis w innym wątku.

 3
Author: dgvid,
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
2012-01-06 14:28:48

Każdy wątek uzyskujący dostęp do pola lotnego odczytuje jego bieżącą wartość przed kontynuacją, zamiast (potencjalnie) używać wartości buforowanej.

Tylko zmienna składowa może być zmienna lub przejściowa.

 3
Author: tstuber,
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
2014-08-11 16:27:12

Istnieją dwa różne zastosowania słowa kluczowego volatile.

  1. uniemożliwia JVM odczytywanie wartości z rejestru (Załóżmy jako cache) i wymusza odczyt jej wartości z pamięci.
  2. zmniejsza ryzyko błędów spójności pamięci.

Uniemożliwia JVM odczyt wartości w rejestrze i wymusza jego wartość odczytywana z pamięci.

A busy flag jest używany, aby zapobiec kontynuowaniu wątku, gdy urządzenie jest zajęte, a flaga nie zabezpieczony zamkiem:

while (busy) {
    /* do something else */
}

Testowanie wątku będzie kontynuowane, gdy inny wątek wyłączy flagę busy :

busy = 0;

Jednakże, ponieważ busy jest często dostępny w wątku testowym, JVM może zoptymalizować test poprzez umieszczenie wartości busy w rejestrze, a następnie przetestować zawartość rejestru bez odczytywania wartości busy w pamięci przed każdym testem. Wątek testowy nigdy nie zobaczy zmiany zajętości, a drugi wątek zmieni tylko wartość zajętości w pamięć, co prowadzi do impasu. Zadeklarowanie znacznika busy jako lotnego wymusza odczytanie jego wartości przed każdym testem.

Zmniejsza ryzyko błędów spójności pamięci.

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

Technika czytania, pisania bez błędów spójności pamięci nazywa się działaniem atomowym.

Akcja atomowa to taka, która skutecznie dzieje się naraz. Akcja atomowa nie może zatrzymać się w środku: albo dzieje się całkowicie, albo wcale. Żadne efekty uboczne działania atomowego nie są widoczne aż do zakończenia działania.

Poniżej znajdują się akcje, które można określić jako atomowe:

  • czyta i pisze są atomowych dla zmiennych referencyjnych i dla większości zmienne prymitywne (wszystkie typy z wyjątkiem long I double).
  • odczyty i zapisy są atomowe dla wszystkich zmiennych zadeklarowanych lotne (w tym zmienne długie i podwójne).
Zdrówko!
 2
Author: dheeran,
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-02 08:42:57

Zmienne lotne są synchronizacją wagi lekkiej. Gdy wymagana jest widoczność najnowszych danych wśród wszystkich wątków i może być zagrożona atomiczność , w takich sytuacjach należy preferować zmienne zmienne zmienne. Read on volatile variables zawsze zwraca najnowszy zapis wykonywany przez dowolny wątek, ponieważ nie są one ani buforowane w rejestrach, ani w buforach, w których inne procesory nie widzą. Lotny jest wolny od blokady. Używam volatile, gdy scenariusz spełnia kryteria wymienione powyżej.

 2
Author: Neha Vari,
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-02-06 12:57:06

Ze strony Oracle documentation pojawia się potrzeba zmiennej zmienna zmienna zmienna zmienna zmienna zmienna zmienna zmienna zmienna zmienna zmienna zmienna zmienna zmienna zmienna zmienna zmienna zmienna zmienna zmienna zmienna zmienna]}

Używanie zmiennych lotnych zmniejsza ryzyko błędów spójności pamięci, ponieważ każdy zapis do zmiennej lotnej ustanawia relację happens-before z kolejnymi odczytami tej samej zmiennej.

Oznacza to, że zmiany w zmiennej volatile są zawsze widoczne dla innych wątków. Oznacza to również, że gdy wątek czyta ulotną zmienna, widzi nie tylko ostatnią zmianę volatile, ale także skutki uboczne kodu, który doprowadził do zmiany.

Jak wyjaśniono w odpowiedzi Peter Parker, w przypadku braku modyfikatora volatile, stos każdego wątku może mieć własną kopię zmiennej. Zmieniając zmienną na volatile, Naprawiono problemy ze spójnością pamięci.

Aby lepiej zrozumieć, zajrzyj na stronę z samouczkiem jenkov.

Spójrz na powiązane pytanie SE, aby uzyskać więcej szczegółów na temat volatile & przypadki użycia lotnych:

Różnica między lotnym a synchronizowanym w Javie

Jeden praktyczny przypadek użycia:

Masz wiele wątków, które muszą wydrukować bieżący czas w określonym formacie, na przykład: java.text.SimpleDateFormat("HH-mm-ss"). Yon może mieć jedną klasę, która zamienia bieżący czas na SimpleDateFormat i aktualizuje zmienną dla każdej sekundy. Wszystkie inne wątki mogą po prostu użyć tej zmiennej do wydruku bieżącego czasu w plikach dziennika.

 1
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 11:55:13

Zmienna Volatile zmienia się asynchronicznie podczas jednoczesnego wykonywania wątków w aplikacji Java. Nie jest dozwolone posiadanie lokalnej kopii zmiennej, która różni się od wartości aktualnie przechowywanej w pamięci "main". W rzeczywistości zmienna zadeklarowana jako zmienna zmienna musi mieć zsynchronizowane dane we wszystkich wątkach, tak aby za każdym razem, gdy uzyskasz dostęp lub zaktualizujesz zmienną w dowolnym wątku, wszystkie inne wątki natychmiast widzą tę samą wartość. Oczywiście jest prawdopodobne, że zmienne zmienne mają większy dostęp I update niż zmienne" zwykłe", ponieważ powodem, dla którego wątki mogą mieć własną kopię danych, jest lepsza wydajność.

Gdy pole jest zadeklarowane jako lotne, kompilator i runtime są włączane, że ta zmienna jest współdzielona i że operacje na niej nie powinny być zmieniane z innymi operacjami pamięci.Zmienne lotne nie są buforowane w rejestrach ani w buforach, gdzie są ukryte przed innymi procesorami, więc odczyt zmienna volatile zawsze zwraca najnowszy zapis w dowolnym wątku.

W celach informacyjnych, zapoznaj się z tym http://techno-terminal.blogspot.in/2015/11/what-are-volatile-variables.html

 0
Author: satish,
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-11-17 09:36:43

Klucz Lotny, gdy jest używany ze zmienną, upewni się, że wątki czytające tę zmienną będą widzieć tę samą wartość . Teraz, jeśli masz wiele wątków odczytu i zapisu do zmiennej, co zmienna zmienna nie wystarczy i dane zostaną uszkodzone . Wątki graficzne odczytały tę samą wartość, ale każdy z nich wykonał kilka czatów (np. zwiększony licznik), przy zapisie z powrotem do pamięci naruszana jest integralność danych . Dlatego konieczne jest, aby zmienny synchronized (different ways are possible)

Jeśli zmiany są wykonywane przez 1 wątek, a pozostałe muszą tylko odczytać tę wartość, zmienna będzie odpowiednia.

 0
Author: Java Main,
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-12-24 16:41:21

Lotny nie podąża za nim.

1 > Odczyt i zapis zmiennych lotnych przez różne wątki są zawsze z pamięci, a nie z własnej pamięci podręcznej lub rejestru procesora wątku. Więc każdy wątek zawsze zajmuje się najnowszą wartością. 2 > Gdy 2 różne wątki pracują z tą samą instancją lub zmiennymi statycznymi w stercie, może się zdarzyć, że inne akcje będą Nie w porządku. Zobacz blog jeremy ' ego Mansona na ten temat. Ale lotność tu pomaga.

Po w pełni uruchomionym kodzie pokazuje jak wiele wątków może wykonać w wstępnie zdefiniowana kolejność i drukowanie wyjść bez użycia zsynchronizowanego słowa kluczowego.

thread 0 prints 0
thread 1 prints 1
thread 2 prints 2
thread 3 prints 3
thread 0 prints 0
thread 1 prints 1
thread 2 prints 2
thread 3 prints 3
thread 0 prints 0
thread 1 prints 1
thread 2 prints 2
thread 3 prints 3

Aby to osiągnąć, możemy użyć następującego pełnowartościowego kodu uruchomieniowego.

public class Solution {
    static volatile int counter = 0;
    static int print = 0;
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Thread[] ths = new Thread[4];
        for (int i = 0; i < ths.length; i++) {
            ths[i] = new Thread(new MyRunnable(i, ths.length));
            ths[i].start();
        }
    }
    static class MyRunnable implements Runnable {
        final int thID;
        final int total;
        public MyRunnable(int id, int total) {
            thID = id;
            this.total = total;
        }
        @Override
        public void run() {
            // TODO Auto-generated method stub
            while (true) {
                if (thID == counter) {
                    System.out.println("thread " + thID + " prints " + print);
                    print++;
                    if (print == total)
                        print = 0;
                    counter++;
                    if (counter == total)
                        counter = 0;
                } else {
                    try {
                        Thread.sleep(30);
                    } catch (InterruptedException e) {
                        // log it
                    }
                }
            }
        }
    }
}

Następujący link github ma readme, który daje właściwe Wyjaśnienie. https://github.com/sankar4git/volatile_thread_ordering

 0
Author: sankar banerjee,
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-05-31 06:23:43

I like the jenkov ' s explanation

Słowo kluczowe Java volatile służy do oznaczania zmiennej Java jako "przechowywanej w pamięci głównej". Dokładniej oznacza to, że każdy odczyt zmiennej lotnej będzie odczytywany z pamięci głównej komputera, a nie z pamięci podręcznej procesora, a każdy zapis do zmiennej lotnej będzie zapisywany do pamięci głównej, a nie tylko do pamięci podręcznej procesora.

Właściwie, od Java 5 słowo kluczowe volatile gwarantuje coś więcej niż tylko to zmienne zmienne są zapisywane i odczytywane z pamięci głównej. Jest to rozszerzona gwarancja widoczności tzw. happens-before guarantee.

Względy wydajności lotnych

Odczyt i zapis zmiennych lotnych powoduje, że zmienna jest odczytywana lub zapisywana do pamięci głównej. Odczyt i zapis do pamięci głównej jest droższy niż dostęp do pamięci podręcznej procesora. Dostęp do zmiennych lotnych uniemożliwia również zmianę kolejności instrukcji, co jest normalną wydajnością technika wzmacniająca. Dlatego należy używać zmiennych zmiennych tylko wtedy, gdy naprawdę trzeba wymusić widoczność zmiennych.

 0
Author: yoAlex5,
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-06-16 14:16:55