logo

Illékony kulcsszó Java nyelven

A volatile kulcsszó egy változó értékének különböző szálakkal történő módosítására szolgál. Az osztályszálak biztonságossá tételére is használják. Ez azt jelenti, hogy több szál probléma nélkül használhatja az osztályok egy metódust és példányát egyidejűleg. A volatile kulcsszó primitív típussal vagy objektumokkal is használható.

A volatile kulcsszó nem tárolja gyorsítótárban a változó értékét, és mindig a fő memóriából olvassa be a változót. A volatile kulcsszó nem használható osztályokkal vagy metódusokkal. Azonban változókkal együtt használják. A láthatóságot és a rendelést is garantálja. Megakadályozza a fordítót a kód átrendezésében.

Az adott eszközregiszter tartalma bármikor változhat, ezért szükség van a volatile kulcsszóra, hogy az ilyen hozzáféréseket ne optimalizálja a fordító.

Példa

 class Test { static int var=5; } 

A fenti példában tegyük fel, hogy két szál ugyanazon az osztályon dolgozik. Mindkét szál különböző processzorokon fut, ahol minden szál rendelkezik a var. Ha bármelyik szál módosítja az értékét, a változás nem fog tükröződni a fő memóriában lévő eredetiben. Adatkonzisztenciát okoz, mert a másik szál nem ismeri a módosított értéket.

 class Test { static volatile int var =5; } 

A fenti példában a statikus változók osztálytagok, amelyek meg vannak osztva az összes objektum között. Csak egy példány van a fő memóriában. Az illékony változó értéke soha nem kerül tárolásra a gyorsítótárban. Minden olvasás és írás történik a fő memóriából és a memóriába.

Mikor kell használni?

  • Használhat illékony változót, ha hosszú és dupla változót szeretne automatikusan olvasni és írni.
  • A Java szinkronizálás alternatív módjaként használható.
  • Az írási művelet befejezése után minden olvasószál látni fogja az illékony változó frissített értékét. Ha nem a volatile kulcsszót használja, a különböző olvasószálak eltérő értékeket láthatnak.
  • Arra használják, hogy tájékoztassák a fordítót arról, hogy egy adott utasításhoz több szál is hozzáfér. Megakadályozza, hogy a fordító bármilyen átrendezést vagy optimalizálást végezzen.
  • Ha nem használ illékony változót, a fordító átrendezheti a kódot, szabadon írhat a változó változó gyorsítótárba, ahelyett, hogy a fő memóriából olvasná.

Fontos pontok

  • Használhatja a volatile kulcsszót változókkal. Az illékony kulcsszó használata osztályokkal és metódusokkal illegális.
  • Garantálja, hogy az illékony változó értéke mindig a fő memóriából kerül kiolvasásra, nem a helyi szál gyorsítótárból.
  • Ha a változót illékonynak deklarálta, az olvasás és az írás atomi
  • Csökkenti a memória konzisztencia hibájának kockázatát.
  • A Java illékony változóira írt minden írás egy történést hoz létre, mielőtt ugyanazon változó egymást követő olvasásával kapcsolódna.
  • Az illékony változók mindig láthatók más szálak számára.
  • Az objektumhivatkozásnak számító illékony változó nulla lehet.
  • Ha egy változót nem osztanak meg több szál között, akkor nem kell a volatile kulcsszót használnia ezzel a változóval.

A szinkronizálás és az illékony kulcsszó közötti különbség

A volatile kulcsszó nem helyettesíti a szinkronizált kulcsszót, de bizonyos esetekben alternatívaként használható. A következő különbségek vannak:

Illékony kulcsszó Szinkronizálási kulcsszó
Az illékony kulcsszó egy mezőmódosító. A szinkronizált kulcsszó módosítja a kódblokkokat és a metódusokat.
A szál nem blokkolható a várakozáshoz illékonyság esetén. Szinkronizálás esetén a szálak blokkolhatók várakozásra.
Javítja a szál teljesítményét. A szinkronizált módszerek rontják a szál teljesítményét.
Egyszerre egy változó értékét szinkronizálja a szálmemória és a fő memória között. Szinkronizálja az összes változó értékét a szálmemória és a fő memória között.
Az illékony mezőkre nem vonatkozik a fordítóoptimalizálás. A szinkronizálás a fordító optimalizálásának függvénye.

Példa illékony kulcsszóra

A következő példában definiáltunk egy osztályt, amely növeli a számláló értékét. A Run () metódus a VolatileThread.java fájlban megkapja a frissített értéket és a régi értéket, amikor a szál megkezdi a végrehajtást. A fő osztályban definiáljuk a szál tömbjét.

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;>