Volatile nøkkelord brukes til å endre verdien av en variabel med forskjellige tråder. Den brukes også for å gjøre klassetråden trygg. Det betyr at flere tråder kan bruke en metode og forekomst av klassene samtidig uten problemer. Det flyktige nøkkelordet kan brukes enten med primitiv type eller objekter.
Nøkkelordet volatile cacher ikke verdien til variabelen og leser alltid variabelen fra hovedminnet. Det flyktige nøkkelordet kan ikke brukes med klasser eller metoder. Imidlertid brukes den med variabler. Det garanterer også synlighet og bestilling. Det forhindrer kompilatoren fra å omorganisere kode.
Innholdet i det bestemte enhetsregisteret kan endres når som helst, så du trenger det flyktige nøkkelordet for å sikre at slike tilganger ikke optimaliseres bort av kompilatoren.
Eksempel
class Test { static int var=5; }
I eksemplet ovenfor, anta at to tråder fungerer på samme klasse. Begge trådene kjører på forskjellige prosessorer der hver tråd har sin lokale kopi av var. Hvis en tråd endrer verdien, vil endringen ikke reflekteres i den opprinnelige i hovedminnet. Det fører til datainkonsekvens fordi den andre tråden ikke er klar over den endrede verdien.
class Test { static volatile int var =5; }
I eksemplet ovenfor er statiske variabler klassemedlemmer som deles mellom alle objekter. Det er bare én kopi i hovedminnet. Verdien til en flyktig variabel vil aldri bli lagret i hurtigbufferen. All lesing og skriving vil bli gjort fra og til hovedminnet.
Når skal man bruke det?
- Du kan bruke en flyktig variabel hvis du vil lese og skrive lang og dobbel variabel automatisk.
- Den kan brukes som en alternativ måte å oppnå synkronisering i Java.
- Alle lesertråder vil se den oppdaterte verdien av den flyktige variabelen etter å ha fullført skriveoperasjonen. Hvis du ikke bruker det flyktige søkeordet, kan en annen lesertråd se forskjellige verdier.
- Den brukes til å informere kompilatoren om at flere tråder vil få tilgang til en bestemt setning. Det forhindrer kompilatoren fra å gjøre noen ombestilling eller optimalisering.
- Hvis du ikke bruker volatile variabel kompilator kan omorganisere koden, gratis å skrive i cache verdi av volatile variabel i stedet for å lese fra hovedminnet.
Viktige poeng
- Du kan bruke det flyktige søkeordet med variabler. Å bruke flyktige søkeord med klasser og metoder er ulovlig.
- Den garanterer at verdien av den flyktige variabelen alltid vil bli lest fra hovedminnet, ikke fra den lokale trådbufferen.
- Hvis du erklærte variabel som flyktig, er Les og skriver atomære
- Det reduserer risikoen for minnekonsistensfeil.
- Enhver skriving til flyktig variabel i Java etablerer en hendelse før forholdet med påfølgende lesninger av den samme variabelen.
- De flyktige variablene er alltid synlige for andre tråder.
- Den flyktige variabelen som er en objektreferanse kan være null.
- Når en variabel ikke deles mellom flere tråder, trenger du ikke bruke det flyktige søkeordet med den variabelen.
Forskjellen mellom synkronisering og flyktige søkeord
Volatile søkeord er ikke en erstatning for synkroniserte nøkkelord, men det kan brukes som et alternativ i visse tilfeller. Det er følgende forskjeller:
Flyktig søkeord | Synkronisering nøkkelord |
---|---|
Volatile nøkkelord er en feltmodifikator. | Synkronisert nøkkelord endrer kodeblokker og metoder. |
Tråden kan ikke blokkeres for venting i tilfelle flyktig. | Tråder kan blokkeres for venting ved synkronisering. |
Det forbedrer trådytelsen. | Synkroniserte metoder forringer trådytelsen. |
Den synkroniserer verdien av én variabel om gangen mellom trådminne og hovedminne. | Den synkroniserer verdien av alle variabler mellom trådminne og hovedminne. |
Volatile felt er ikke gjenstand for kompilatoroptimalisering. | Synkronisering er underlagt kompilatoroptimalisering. |
Eksempel på flyktig søkeord
I følgende eksempel har vi definert en klasse som øker tellerverdien. Run ()-metoden i VolatileThread.java får den oppdaterte verdien og den gamle verdien når tråden begynner å kjøre. I hovedklassen definerer vi tråden.
VolatileData.java
public class VolatileData { private volatile int counter = 0; public int getCounter() { return counter; } public void increaseCounter() { ++counter; //increases the value of counter by 1 } }
VolatileThread.java
VolatileThread.java public class VolatileThread extends Thread { private final VolatileData data; public VolatileThread(VolatileData data) { this.data = data; } @Override public void run() { int oldValue = data.getCounter(); System.out.println('[Thread ' + Thread.currentThread().getId() + ']: Old value = ' + oldValue); data.increaseCounter(); int newValue = data.getCounter(); System.out.println('[Thread ' + Thread.currentThread().getId() + ']: New value = ' + newValue); } }
VolatileMain.java
public class VolatileMain { private final static int noOfThreads = 2; public static void main(String[] args) throws InterruptedException { VolatileData volatileData = new VolatileData(); //object of VolatileData class Thread[] threads = new Thread[noOfThreads]; //creating Thread array for(int i = 0; i <noofthreads; ++i) threads[i]="new" volatilethread(volatiledata); for(int i="0;" < noofthreads; threads[i].start(); starts all reader threads threads[i].join(); wait for } pre> <p> <strong>Output:</strong> </p> <pre> [Thread 9]: Old value = 0 [Thread 9]: New value = 1 [Thread 10]: Old value = 1 [Thread 10]: New value = 2 </pre> <hr></noofthreads;>