Ključna riječ volatile koristi se za izmjenu vrijednosti varijable od strane različitih niti. Također se koristi kako bi klase bile niti sigurne. To znači da više niti može koristiti metodu i instancu klasa u isto vrijeme bez ikakvih problema. Ključna riječ volatile može se koristiti s primitivnim tipom ili objektima.
Ključna riječ volatile ne sprema vrijednost varijable u predmemoriju i uvijek čita varijablu iz glavne memorije. Ključna riječ volatile ne može se koristiti s klasama ili metodama. Međutim, koristi se s varijablama. Također jamči vidljivost i redoslijed. Sprječava kompajler od promjene redoslijeda koda.
string java replace
Sadržaj registra određenog uređaja može se promijeniti u bilo kojem trenutku, tako da vam je potrebna ključna riječ volatile kako biste osigurali da takve pristupe ne optimizira prevodilac.
Primjer
class Test { static int var=5; }
U gornjem primjeru pretpostavimo da dvije niti rade na istoj klasi. Obje niti rade na različitim procesorima gdje svaka nit ima svoju lokalnu kopiju var. Ako bilo koja nit promijeni svoju vrijednost, promjena se neće odraziti na izvornu u glavnoj memoriji. To dovodi do nedosljednosti podataka jer druga nit nije svjesna modificirane vrijednosti.
class Test { static volatile int var =5; }
U gornjem primjeru, statičke varijable su članovi klase koje dijele svi objekti. Postoji samo jedna kopija u glavnoj memoriji. Vrijednost volatilne varijable nikada neće biti pohranjena u predmemoriju. Sva čitanja i pisanja vršit će se iz i u glavnu memoriju.
Kada ga koristiti?
- Možete koristiti volatile varijablu ako želite automatski čitati i pisati dugu i dvostruku varijablu.
- Može se koristiti kao alternativni način postizanja sinkronizacije u Javi.
- Sve niti čitača vidjet će ažuriranu vrijednost volatile varijable nakon završetka operacije pisanja. Ako ne koristite ključnu riječ volatile, različite niti čitača mogu vidjeti različite vrijednosti.
- Koristi se za informiranje kompajlera da će više niti pristupiti određenoj izjavi. Sprječava kompajler u bilo kakvom preuređenju ili optimizaciji.
- Ako ne koristite volatile varijablu prevodilac može promijeniti redoslijed koda, slobodno pisati u predmemoriju vrijednost volatile varijable umjesto čitanja iz glavne memorije.
Važne točke
- Možete koristiti ključnu riječ volatile s varijablama. Korištenje volatile ključne riječi s klasama i metodama je protuzakonito.
- Jamči da će se vrijednost volatilne varijable uvijek čitati iz glavne memorije, a ne iz lokalne predmemorije niti.
- Ako ste deklarirali varijablu kao volatile, Read i Writes su atomski
- Smanjuje rizik od pogreške dosljednosti memorije.
- Svako pisanje u volatile varijablu u Javi uspostavlja događaj prije odnosa s uzastopnim čitanjima te iste varijable.
- Nestalne varijable uvijek su vidljive drugim nitima.
- Varijabla volatile koja je referenca objekta može biti null.
- Kada se varijabla ne dijeli između više niti, ne morate koristiti ključnu riječ volatile s tom varijablom.
Razlika između sinkronizacije i volatile ključne riječi
Nestalna ključna riječ nije zamjena za sinkroniziranu ključnu riječ, ali se u određenim slučajevima može koristiti kao alternativa. Postoje sljedeće razlike:
Nestalna ključna riječ | Ključna riječ za sinkronizaciju |
---|---|
Ključna riječ volatile je modifikator polja. | Sinkronizirana ključna riječ mijenja blokove koda i metode. |
Nit se ne može blokirati zbog čekanja u slučaju nestabilnosti. | Niti se mogu blokirati zbog čekanja u slučaju sinkronizacije. |
Poboljšava performanse niti. | Sinkronizirane metode smanjuju izvedbu niti. |
Sinkronizira vrijednost jedne po jedne varijable između memorije niti i glavne memorije. | Sinkronizira vrijednost svih varijabli između memorije niti i glavne memorije. |
Nestalna polja ne podliježu optimizaciji prevoditelja. | Sinkronizacija podliježe optimizaciji prevoditelja. |
Primjer nestabilne ključne riječi
U sljedećem primjeru definirali smo klasu koja povećava vrijednost brojača. Metoda run () u VolatileThread.java dobiva ažuriranu vrijednost i staru vrijednost kada nit započne izvršavanje. U glavnoj klasi definiramo niz niti.
VolatileData.java
poravnavanje slika u css-u
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;>