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:
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?
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.
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.
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
:
- synchronizacja w Javie jest możliwa poprzez użycie słów kluczowych Java
synchronized
ivolatile
oraz zamków. - w Javie nie możemy mieć zmiennej
synchronized
. Użycie słowa kluczowegosynchronized
ze zmienną jest nielegalne i spowoduje błąd kompilacji. Zamiast używać zmiennejsynchronized
w języku Java, możesz użyć zmiennej javavolatile
, która poinstruuje wątki JVM, aby odczytały wartość zmiennejvolatile
z pamięci głównej i nie buforowały jej lokalnie. - jeśli zmienna nie jest współdzielona między wieloma wątkami, nie ma potrzeby używania słowa kluczowego
volatile
.
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
volatile
zastosowanie w Java :
volatile
na obiekcie list.
- gdy lista jest aktualizowana, licznik jest zwiększany.
- kiedy tworzony jest
Iterator
, bieżąca wartość licznika jest osadzana w obiekcieIterator
. - gdy wykonywana jest operacja
Iterator
, metoda porównuje dwie wartości licznika i rzucaConcurrentModificationException
, 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.
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
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
.
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.
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
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
-
Podwójnie sprawdzony mechanizm blokujący . Często używane w Singleton design
wzór. W tym
singleton object needs to be declared volatile
. -
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
.
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ą.
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.
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 kluczowegovolatile
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.
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".
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);
}
}
}
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ć:
- 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.
- 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.
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.
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.
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.
- uniemożliwia JVM odczytywanie wartości z rejestru (Załóżmy jako cache) i wymusza odczyt jej wartości z pamięci.
- 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).
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.
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.
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.
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
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.
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
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.
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