logo

Java Atomic

I Java, atomvariabler och operationer används samtidigt. De flertrådig miljö leder till ett problem när samtidighet är enat. Den delade enheten såsom objekt och variabler kan ändras under körningen av programmet. Därför kan de leda till inkonsekvens i programmet. Så det är viktigt att ta hand om den delade enheten samtidigt som du får åtkomst. I sådana fall är atomvariabel kan vara en lösning på det. I det här avsnittet kommer vi att diskutera atomklasser, atomvariabler, atomoperationer , tillsammans med exempel.

xor i c++

Innan du går vidare i det här avsnittet, se till att du är medveten om tråd , synkronisering , och låsa i Java.

Java Atomic klasser

Java ger en java.util.concurrent.atomic paket där atomklasser definieras. Atomklasserna ger en låsfri och trådsäker miljö eller programmering på en enda variabel. Den stöder också atomoperationer. Alla atomklasser har metoderna get() och set() som fungerar på den flyktiga variabeln. Metoden fungerar på samma sätt som att läsa och skriva på flyktiga variabler.

Paketet innehåller följande atomklasser:

Klass Beskrivning
AtomicBoolean Den används för att uppdatera booleskt värde atomärt.
AtomicInteger Den används för att uppdatera heltalsvärden atomärt.
AtomicIntegerArray En int-matris där element kan uppdateras atomärt.
AtomicIntegerFieldUpdater Ett reflektionsbaserat verktyg som möjliggör atomära uppdateringar av angivna flyktiga int-fält av angivna klasser.
AtomicLong Den används för att uppdatera långa värden atomärt.
AtomicLongArray En lång array där element kan uppdateras atomärt.
AtomicLongFieldUpdater Ett reflektionsbaserat verktyg som möjliggör atomära uppdateringar av angivna flyktiga långa fält av angivna klasser.
AtomicMarkableReference En AtomicMarkableReference upprätthåller en objektreferens tillsammans med en markbit, som kan uppdateras atomärt.
AtomicReference En objektreferens som kan uppdateras atomärt.
AtomicReferenceArray En uppsättning objektreferenser där element kan uppdateras atomärt.
AtomicReferenceFieldUpdater Ett reflektionsbaserat verktyg som möjliggör atomära uppdateringar av angivna flyktiga referensfält av angivna klasser.
AtomicStampedReference En AtomicStampedReference upprätthåller en objektreferens tillsammans med ett heltals 'stämpel', som kan uppdateras atomärt.
Dubbel ackumulator En eller flera variabler som tillsammans upprätthåller ett löpande dubbelvärde uppdaterat med hjälp av en medföljande funktion.
DoubleAdder En eller flera variabler som tillsammans upprätthåller en initialt noll dubbelsumma.
Lång ackumulator En eller flera variabler som tillsammans upprätthåller ett löpande långt värde uppdaterat med hjälp av en medföljande funktion.
LongAdder En eller flera variabler som tillsammans upprätthåller en initialt noll lång summa.

Objekt av dessa klasser representerar atomvariabeln av int, lång, boolesk , och objekt referens respektive. Atomklasserna har några vanliga metoder är följande:

Metoder Beskrivning
uppsättning() Den används för att ställa in värdet.
skaffa sig() Den används för att få det aktuella värdet.
lazySet() Ställer så småningom till det givna värdet.
compareAndSet Atomically sätter värdet till det givna uppdaterade värdet om det aktuella värdet == det förväntade värdet.

Atomverksamhet

De operationer som alltid körs tillsammans kallas atomära operationer eller atomär verkan . Alla atomoperationer som antingen utförs på ett effektivt sätt sker alla på en gång eller så händer de inte alls. Tre nyckelbegrepp som är förknippade med atomära åtgärder i Java är följande:

1. Atomicitet handlar om vilka handlingar och uppsättningar o handlingar har osynlig Tänk till exempel på följande kodavsnitt:

 class NoAtomicOps { long counter=0; void increment() { for(;;) { count++; } } void decrement() { for(;;) { count--; } } //other statement } 

I ovanstående kod är beteendet att köra increment() och decrement() samtidigt odefinierad och inte förutsägbart .

2. Synlighet avgör när effekten av en tråd kan bli sett av en annan. Tänk till exempel på följande kodavsnitt:

 class InfiniteLoop { boolean done= false; void work() { //thread T2 read while(!done) { //do work } } void stopWork() { //thread T1 write done=true; } //statements } 

I ovanstående kod är det möjligt att tråden T2 aldrig kommer att sluta även efter att tråden T1 ställts in på sant. Inte heller att det inte finns någon synkronisering mellan trådar.

3. Ordning avgör när åtgärder i en tråd inträffar ur ordning med avseende på en annan tråd.

 class Order { boolean a=false; boolean b=false; void demo1() //thread T1 { a=true; b=true; } boolean demo2() //thread T2 { boolean r1=b; //sees true boolean r2=a; //sees false boolean r3=a; //sees true //returns true return (r1 && !r2) && r3; } } 

Ordningen som fälten a och b visas i tråd T2 kan skilja sig från den ordning de sattes i tråd T1.

alfabetets nummer

Låt oss förstå det genom ett exempel.

 public class AtomicExample { int count; public void incrementCount() { count=1; } 

I ovanstående kodavsnitt har vi deklarerat en variabel av typen int räkna och inuti metoden incrementCount() tilldelade den till 1. I ett sådant fall händer antingen allt samtidigt eller inte alls. Därför representerar den en atomär drift och operationen är känd som atomicitet .

Låt oss överväga ett annat kodavsnitt.

 public class AtomicExample { int count; public void incrementCount() { count=count+1; } 

Det verkar som att det också är en atomoperation men inte så. Det är en linjär operation som består av tre operationer, dvs läsa, modifiera och skriva. Därför kan den köras delvis. Men om vi använder ovanstående kod i en flertrådig miljö skapar det ett problem.

Antag att vi har anropat ovanstående kod i en enkeltrådig miljö, det uppdaterade värdet på count kommer att vara 2. Om vi ​​anropar ovanstående metod med två separata trådar, kommer de både åt variabeln samtidigt och uppdaterar även värdet på räkna samtidigt. För att undvika denna situation använder vi atomär drift.

knappen för att centrera css

Java stöder flera typer av atomära åtgärder, är följande:

  • Flyktig variabler
  • Atomoperationer på låg nivå (osäkra)
  • Atomklasser

Låt oss se hur vi kan skapa en atomär operation.

Atomvariabel

Atomvariabeln tillåter oss att utföra en atomoperation på en variabel. Atomvariabler minimerar synkronisering och hjälper till att undvika minneskonsistensfel. Därför säkerställer det synkronisering.

konvertera sträng till json java

Atompaketet tillhandahåller följande fem atomvariabler:

  • AtomicInteger
  • AtomicLong
  • AtomicBoolean
  • AtomicIntegerArray
  • AtomicLongArray

Behovet av atomvariabel

Låt oss överväga följande kod.

Counter.java

 class Counter extends Thread { // Counter Variable int count = 0; //the method starts the execution of a thread public void run() { int max = 1; //increments the counter variable up to specified max time for (int i = 0; i <max; i++) { count++; } public class counter static void main(string args[]) throws interruptedexception creating an instance of the c="new" counter(); four threads thread t1="new" thread(c, 'first'); t2="new" 'second'); t3="new" 'third'); t4="new" 'fourth'); by calling start() method, we have started t1.start(); t2.start(); t3.start(); t4.start(); main will wait for all until execution do not complete t1.join(); t2.join(); t3.join(); t4.join(); prints final value count variable system.out.println(c.count); < pre> <p> <strong>Output:</strong> </p> <pre> 4 </pre> <p>The above program gives the expected output if it is executed in a single-threaded environment. A multi-threaded environment may lead to unexpected output. The reason behind it that when two or more threads try to update the value at the same time then it may not update properly.</p> <p>Java offers <strong>two</strong> solutions to overcome this problem:</p> <ul> <li>By using lock and synchronization</li> <li>By using atomic variable</li> </ul> <p>Let&apos;s create a Java program and use an atomic variable to overcome the problem.</p> <h3>By using Atomic Variable</h3> <p> <strong>AtomicExample.java</strong> </p> <pre> class Counter extends Thread { // Counter Variable int count = 0; //the method starts the execution of a thread public void run() { int max = 1; //increments the counter variable up to specified max time for (int i = 0; i <max; i++) { count++; } public class counter static void main(string args[]) throws interruptedexception creating an instance of the c="new" counter(); four threads thread t1="new" thread(c, 'first'); t2="new" 'second'); t3="new" 'third'); t4="new" 'fourth'); by calling start() method, we have started t1.start(); t2.start(); t3.start(); t4.start(); main will wait for all until execution do not complete t1.join(); t2.join(); t3.join(); t4.join(); prints final value count variable system.out.println(c.count); < pre> <p> <strong>Output:</strong> </p> <pre> 4 </pre> <h2>Synchronized Vs. Atomic Vs. Volatile</h2> <table class="table"> <tr> <th>Synchronized</th> <th>Atomic</th> <th>Volatile</th> </tr> <tr> <td>It applies to methods only.</td> <td>It applies to variables only.</td> <td>It also applies to variables only.</td> </tr> <tr> <td>It ensures visibility along with atomicity.</td> <td>It also ensures visibility along with atomicity.</td> <td>It ensures visibility, not atomicity.</td> </tr> <tr> <td>We can&apos;t achieve the same.</td> <td>We can&apos;t achieve the same.</td> <td>It stores in RAM, so accessing volatile variables is fast. But it does not provide thread-safety and synchronization.</td> </tr> <tr> <td>It can be implemented as a synchronized block or a synchronized method.</td> <td>We can&apos;t achieve the same.</td> <td>We can&apos;t achieve the same.</td> </tr> <tr> <td>It can lock the same class object or a different class object.</td> <td>We can&apos;t achieve the same.</td> <td>We can&apos;t achieve the same.</td> </tr> </table> <hr></max;></pre></max;>

Ovanstående program ger den förväntade utdata om det körs i en entrådig miljö. En flertrådig miljö kan leda till oväntade utdata. Anledningen bakom det är att när två eller flera trådar försöker uppdatera värdet samtidigt så kanske det inte uppdateras ordentligt.

Java erbjuder två lösningar för att lösa detta problem:

  • Genom att använda lås och synkronisering
  • Genom att använda atomvariabel

Låt oss skapa ett Java-program och använda en atomvariabel för att övervinna problemet.

Genom att använda Atomic Variable

AtomicExample.java

 class Counter extends Thread { // Counter Variable int count = 0; //the method starts the execution of a thread public void run() { int max = 1; //increments the counter variable up to specified max time for (int i = 0; i <max; i++) { count++; } public class counter static void main(string args[]) throws interruptedexception creating an instance of the c="new" counter(); four threads thread t1="new" thread(c, \'first\'); t2="new" \'second\'); t3="new" \'third\'); t4="new" \'fourth\'); by calling start() method, we have started t1.start(); t2.start(); t3.start(); t4.start(); main will wait for all until execution do not complete t1.join(); t2.join(); t3.join(); t4.join(); prints final value count variable system.out.println(c.count); < pre> <p> <strong>Output:</strong> </p> <pre> 4 </pre> <h2>Synchronized Vs. Atomic Vs. Volatile</h2> <table class="table"> <tr> <th>Synchronized</th> <th>Atomic</th> <th>Volatile</th> </tr> <tr> <td>It applies to methods only.</td> <td>It applies to variables only.</td> <td>It also applies to variables only.</td> </tr> <tr> <td>It ensures visibility along with atomicity.</td> <td>It also ensures visibility along with atomicity.</td> <td>It ensures visibility, not atomicity.</td> </tr> <tr> <td>We can&apos;t achieve the same.</td> <td>We can&apos;t achieve the same.</td> <td>It stores in RAM, so accessing volatile variables is fast. But it does not provide thread-safety and synchronization.</td> </tr> <tr> <td>It can be implemented as a synchronized block or a synchronized method.</td> <td>We can&apos;t achieve the same.</td> <td>We can&apos;t achieve the same.</td> </tr> <tr> <td>It can lock the same class object or a different class object.</td> <td>We can&apos;t achieve the same.</td> <td>We can&apos;t achieve the same.</td> </tr> </table> <hr></max;>

Synkroniserad vs. Atomic vs. Flyktig

Synkroniserad Atom Flyktig
Det gäller endast metoder. Det gäller endast variabler. Det gäller även endast variabler.
Det säkerställer synlighet tillsammans med atomicitet. Det säkerställer också synlighet tillsammans med atomicitet. Det säkerställer synlighet, inte atomicitet.
Vi kan inte uppnå samma sak. Vi kan inte uppnå samma sak. Det lagras i RAM, så det går snabbt att komma åt flyktiga variabler. Men det ger inte trådsäkerhet och synkronisering.
Det kan implementeras som ett synkroniserat block eller en synkroniserad metod. Vi kan inte uppnå samma sak. Vi kan inte uppnå samma sak.
Det kan låsa samma klassobjekt eller ett annat klassobjekt. Vi kan inte uppnå samma sak. Vi kan inte uppnå samma sak.