logo

Volatilné kľúčové slovo v jazyku Java

Volatilné kľúčové slovo sa používa na úpravu hodnoty premennej rôznymi vláknami. Používa sa tiež na zaistenie bezpečnosti tried pre vlákna. Znamená to, že metódu a inštanciu tried môže bez problémov používať viacero vlákien súčasne. Nestále kľúčové slovo možno použiť buď s primitívnym typom alebo objektmi.

Nestále kľúčové slovo neukladá do vyrovnávacej pamäte hodnotu premennej a vždy číta premennú z hlavnej pamäte. Nestále kľúčové slovo nemožno použiť s triedami alebo metódami. Používa sa však s premennými. Zaručuje tiež viditeľnosť a usporiadanie. Zabraňuje kompilátoru v zmene poradia kódu.

Obsah konkrétneho registra zariadenia sa môže kedykoľvek zmeniť, takže potrebujete kľúčové slovo volatile, aby ste zabezpečili, že takéto prístupy nebudú kompilátorom optimalizované.

livecricket.is

Príklad

 class Test { static int var=5; } 

Vo vyššie uvedenom príklade predpokladajme, že dve vlákna pracujú na rovnakej triede. Obe vlákna bežia na rôznych procesoroch, pričom každé vlákno má svoju lokálnu kópiu var. Ak niektoré vlákno zmení svoju hodnotu, zmena sa neprejaví v pôvodnom v hlavnej pamäti. Vedie to k nekonzistentnosti údajov, pretože druhé vlákno nevie o zmenenej hodnote.

 class Test { static volatile int var =5; } 

Vo vyššie uvedenom príklade sú statické premenné členmi triedy, ktoré sú zdieľané medzi všetkými objektmi. V hlavnej pamäti je len jedna kópia. Hodnota volatilnej premennej sa nikdy neuloží do vyrovnávacej pamäte. Všetko čítanie a zápis sa bude vykonávať z hlavnej pamäte a do hlavnej pamäte.

vstup java

Kedy ho použiť?

  • Volile premennú môžete použiť, ak chcete automaticky čítať a zapisovať dlhé a dvojité premenné.
  • Môže byť použitý ako alternatívny spôsob dosiahnutia synchronizácie v jazyku Java.
  • Všetky vlákna čítačky uvidia aktualizovanú hodnotu volatilnej premennej po dokončení operácie zápisu. Ak nepoužívate nestále kľúčové slovo, rôzne vlákna čítačky môžu vidieť rôzne hodnoty.
  • Používa sa na informovanie kompilátora, že k určitému príkazu bude pristupovať viacero vlákien. Zabraňuje to kompilátoru v akejkoľvek zmene poradia alebo akejkoľvek optimalizácii.
  • Ak nepoužívate volatilné premenné kompilátor môže zmeniť poradie kódu, môžete zapísať do cache hodnotu volatilnej premennej namiesto čítania z hlavnej pamäte.

Dôležité body

  • Kľúčové slovo volatile môžete použiť s premennými. Používanie nestálych kľúčových slov s triedami a metódami je nezákonné.
  • Zaručuje, že hodnota volatilnej premennej bude vždy načítaná z hlavnej pamäte, nie z lokálnej vyrovnávacej pamäte vlákien.
  • Ak ste premennú deklarovali ako nestálu, čítanie a zápis sú atómové
  • Znižuje riziko chyby konzistencie pamäte.
  • Akýkoľvek zápis do prchavej premennej v jazyku Java sa uskutoční pred vzťahom s postupným čítaním tej istej premennej.
  • Nestále premenné sú vždy viditeľné pre ostatné vlákna.
  • Prchavá premenná, ktorá je odkazom na objekt, môže mať hodnotu null.
  • Keď premenná nie je zdieľaná medzi viacerými vláknami, nemusíte s touto premennou používať nestále kľúčové slovo.

Rozdiel medzi synchronizáciou a nestálym kľúčovým slovom

Nestále kľúčové slovo nie je náhradou synchronizovaného kľúčového slova, ale v určitých prípadoch ho možno použiť ako alternatívu. Existujú nasledujúce rozdiely:

Prchavé kľúčové slovo Kľúčové slovo synchronizácie
Nestále kľúčové slovo je modifikátor poľa. Synchronizované kľúčové slovo upravuje bloky kódu a metódy.
Vlákno nemožno zablokovať na čakanie v prípade volatile. Vlákna je možné v prípade synchronizácie zablokovať na počkanie.
Zlepšuje výkon vlákna. Synchronizované metódy znižujú výkon vlákna.
Synchronizuje hodnotu jednej premennej naraz medzi pamäťou vlákien a hlavnou pamäťou. Synchronizuje hodnotu všetkých premenných medzi pamäťou vlákien a hlavnou pamäťou.
Nestále polia nepodliehajú optimalizácii kompilátora. Synchronizácia podlieha optimalizácii kompilátora.

Príklad nestáleho kľúčového slova

V nasledujúcom príklade sme definovali triedu, ktorá zvyšuje hodnotu počítadla. Metóda run () v VolatileThread.java získa aktualizovanú hodnotu a starú hodnotu, keď sa vlákno začne vykonávať. V hlavnej triede definujeme pole vlákien.

VolatileData.java

pole zoradené v jazyku 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;>