logo

Flyktiga nyckelord i Java

Volatile nyckelord används för att ändra värdet på en variabel med olika trådar. Det används också för att göra klasser trådsäkra. Det betyder att flera trådar kan använda en metod och instans av klasserna samtidigt utan problem. Det flyktiga nyckelordet kan användas antingen med primitiv typ eller objekt.

du är skarv

Nyckelordet volatile cachelagrar inte variabelns värde och läser alltid variabeln från huvudminnet. Det flyktiga nyckelordet kan inte användas med klasser eller metoder. Det används dock med variabler. Det garanterar också synlighet och ordning. Det hindrar kompilatorn från att ordna om koden.

Innehållet i det specifika enhetsregistret kan ändras när som helst, så du behöver det flyktiga nyckelordet för att säkerställa att sådana åtkomster inte optimeras bort av kompilatorn.

Exempel

 class Test { static int var=5; } 

I exemplet ovan, anta att två trådar fungerar på samma klass. Båda trådarna körs på olika processorer där varje tråd har sin lokala kopia av var. Om någon tråd ändrar sitt värde kommer ändringen inte att återspeglas i den ursprungliga i huvudminnet. Det leder till datainkonsekvens eftersom den andra tråden inte är medveten om det modifierade värdet.

 class Test { static volatile int var =5; } 

I exemplet ovan är statiska variabler klassmedlemmar som delas mellan alla objekt. Det finns bara en kopia i huvudminnet. Värdet på en flyktig variabel kommer aldrig att lagras i cachen. All läsning och skrivning kommer att göras från och till huvudminnet.

När ska man använda det?

  • Du kan använda en volatil variabel om du vill läsa och skriva lång och dubbel variabel automatiskt.
  • Det kan användas som ett alternativt sätt att uppnå synkronisering i Java.
  • Alla läsartrådar kommer att se det uppdaterade värdet för den flyktiga variabeln efter att ha slutfört skrivoperationen. Om du inte använder det flyktiga nyckelordet kan olika läsartrådar se olika värden.
  • Den används för att informera kompilatorn om att flera trådar kommer att komma åt ett visst uttalande. Det hindrar kompilatorn från att göra någon omordning eller optimering.
  • Om du inte använder flyktiga variabel kompilator kan ordna om koden, gratis att skriva i cache-värdet av flyktiga variabel istället för att läsa från huvudminnet.

Viktiga punkter

  • Du kan använda nyckelordet volatile med variabler. Att använda flyktiga nyckelord med klasser och metoder är olagligt.
  • Det garanterar att värdet på den flyktiga variabeln alltid kommer att läsas från huvudminnet, inte från den lokala trådcachen.
  • Om du deklarerade variabel som flyktig är Read och Writer atomära
  • Det minskar risken för minneskonsistensfel.
  • Varje skrivning till flyktig variabel i Java etablerar en händelse före relationen med successiva läsningar av samma variabel.
  • De flyktiga variablerna är alltid synliga för andra trådar.
  • Den flyktiga variabeln som är en objektreferens kan vara null.
  • När en variabel inte delas mellan flera trådar behöver du inte använda det flyktiga nyckelordet med den variabeln.

Skillnad mellan synkronisering och flyktigt nyckelord

Flyktiga nyckelord är inte en ersättning för synkroniserade nyckelord, men det kan användas som ett alternativ i vissa fall. Det finns följande skillnader:

Flyktiga nyckelord Nyckelord för synkronisering
Flyktiga nyckelord är en fältmodifierare. Synkroniserat nyckelord ändrar kodblock och metoder.
Tråden kan inte blockeras för att vänta i händelse av flyktig. Trådar kan blockeras för att vänta vid synkronisering.
Det förbättrar trådens prestanda. Synkroniserade metoder försämrar trådens prestanda.
Den synkroniserar värdet på en variabel åt gången mellan trådminnet och huvudminnet. Den synkroniserar värdet på alla variabler mellan trådminne och huvudminne.
Volatila fält är inte föremål för kompilatoroptimering. Synkronisera är föremål för kompilatoroptimering.

Exempel på flyktigt sökord

I följande exempel har vi definierat en klass som ökar räknarvärdet. Metoden kör () i VolatileThread.java får det uppdaterade värdet och det gamla värdet när tråden börjar köras. I huvudklassen definierar 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;>