logo

Java Atomic

V Javi, atomske spremenljivke in operacije uporabljeni sočasno. The večnitnost okolje vodi v težavo, ko sočasnost je poenoten. Entitete v skupni rabi, kot so objekti in spremenljivke, se lahko spremenijo med izvajanjem programa. Zato lahko povzročijo nedoslednost programa. Zato je pomembno, da med sočasnim dostopom skrbite za skupno entiteto. V takih primerih je atomska spremenljivka je lahko rešitev za to. V tem razdelku bomo razpravljali atomski razredi, atomske spremenljivke, atomske operacije , skupaj s primeri.

seštevalnik poln

Preden nadaljujete s tem razdelkom, se prepričajte, da se zavedate nit , sinhronizacijo , in zaklepanje v Javi.

Atomski razredi Java

Java zagotavlja a java.util.concurrent.atomic paket, v katerem so definirani atomski razredi. Atomski razredi zagotavljajo a brez zaklepanja in nitno varen okolje ali programiranje na eno spremenljivko. Podpira tudi atomske operacije. Vsi atomski razredi imajo metodi get() in set(), ki delujeta na volatile spremenljivko. Metoda deluje enako kot branje in pisanje na nestanovitne spremenljivke.

Paket ponuja naslednje atomske razrede:

Razred Opis
AtomicBoolean Uporablja se za atomsko posodobitev logične vrednosti.
AtomicInteger Uporablja se za atomsko posodobitev celoštevilske vrednosti.
AtomicIntegerArray Matrika int, v kateri se lahko elementi posodabljajo atomsko.
AtomicIntegerFieldUpdater Pripomoček, ki temelji na refleksiji in omogoča atomske posodobitve določenih hlapljivih polj int določenih razredov.
AtomicLong Uporablja se za atomsko posodobitev dolge vrednosti.
AtomicLongArray Dolga matrika, v kateri se elementi lahko posodobijo atomsko.
AtomicLongFieldUpdater Pripomoček, ki temelji na refleksiji in omogoča atomske posodobitve določenih hlapljivih dolgih polj določenih razredov.
AtomicMarkableReference AtomicMarkableReference vzdržuje referenco objekta skupaj z bitom oznake, ki ga je mogoče posodobiti atomsko.
AtomicReference Referenca objekta, ki se lahko posodobi atomsko.
AtomicReferenceArray Matrika objektnih referenc, v kateri se elementi lahko posodobijo atomsko.
AtomicReferenceFieldUpdater Pripomoček na osnovi refleksije, ki omogoča atomske posodobitve določenih hlapljivih referenčnih polj določenih razredov.
AtomicStampedReference AtomicStampedReference vzdržuje referenco objekta skupaj s celoštevilskim 'žigom', ki ga je mogoče posodobiti atomsko.
DoubleAccumulator Ena ali več spremenljivk, ki skupaj vzdržujejo tekočo dvojno vrednost, posodobljeno s pomočjo podane funkcije.
DoubleAdder Ena ali več spremenljivk, ki skupaj vzdržujejo prvotno ničelno dvojno vsoto.
LongAccumulator Ena ali več spremenljivk, ki skupaj vzdržujejo tekočo dolgo vrednost, posodobljeno s pomočjo priložene funkcije.
LongAdder Ena ali več spremenljivk, ki skupaj ohranjajo začetno dolgo vsoto nič.

Objekti teh razredov predstavljajo atomsko spremenljivko int, long, boolean , in ugovor referenca oz. Atomski razredi imajo nekaj skupnih metod, kot sledi:

Metode Opis
set() Uporablja se za nastavitev vrednosti.
dobiti () Uporablja se za pridobitev trenutne vrednosti.
lazySet() Na koncu se nastavi na dano vrednost.
compareAndSet Atomično nastavi vrednost na dano posodobljeno vrednost, če je trenutna vrednost == pričakovani vrednosti.

Atomske operacije

Tiste operacije, ki se vedno izvajajo skupaj, so znane kot atomske operacije oz atomsko delovanje . Vse atomske operacije, ki se učinkovito izvedejo, se zgodijo naenkrat ali pa se sploh ne zgodijo. tri ključni koncepti, povezani z atomskimi dejanji v Javi, so naslednji:

1. Atomičnost se ukvarja s tem, katera dejanja in nizi dejanj imajo neviden Na primer, upoštevajte naslednji delček kode:

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

V zgornji kodi je vedenje hkratnega izvajanja increment() in decrement() enako nedoločeno in ni predvidljivo .

2. Vidnost določa, kdaj je lahko učinek ene niti videl s strani drugega. Na primer, upoštevajte naslednji delček kode:

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

V zgornji kodi je možno, da se nit T2 ne bo nikoli ustavila, tudi potem ko se nit T1 nastavi na true. Prav tako ne, da ni sinhronizacije med nitmi.

3. Vrstni red določa, kdaj se dejanja v eni niti zgodijo v nasprotnem vrstnem redu glede na drugo nit.

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

Vrstni red prikaza polj a in b v niti T2 se lahko razlikuje od vrstnega reda, ki sta bila nastavljena v niti T1.

tat polna oblika

Razumejmo to skozi primer.

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

V zgornjem delčku kode smo deklarirali spremenljivko tipa int štetje in znotraj metode incrementCount() ga je dodelil 1. V takem primeru se zgodi vse skupaj ali pa se sploh ne zgodi. Zato predstavlja atomsko delovanje in operacija je znana kot atomičnost .

Oglejmo si še en delček kode.

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

Zdi se, da gre tudi za atomsko operacijo, vendar ni tako. Je linearna operacija, ki je sestavljena iz treh operacij, tj. branja, spreminjanja in pisanja. Zato se lahko izvede delno. Toda če zgornjo kodo uporabljamo v večnitnem okolju, to povzroči težavo.

Recimo, da smo poklicali zgornjo kodo v okolju z eno nitjo, bo posodobljena vrednost count 2. Če zgornjo metodo pokličemo z dvema ločenima nitima, obe hkrati dostopata do spremenljivke in prav tako posodobita vrednost šteti hkrati. Da bi se izognili tej situaciji, uporabljamo atomsko delovanje.

algoritem za razvrščanje kopice

Java podpira več vrst atomskih dejanj, ki so naslednja:

  • Hlapljivo spremenljivke
  • Atomske operacije na nizki ravni (nevarno)
  • Atomski razredi

Poglejmo, kako lahko ustvarimo atomsko operacijo.

Atomska spremenljivka

Atomska spremenljivka nam omogoča izvedbo atomske operacije na spremenljivki. Atomične spremenljivke minimizirajo sinhronizacijo in se izognejo napakam skladnosti pomnilnika. Zato zagotavlja sinhronizacijo.

Atomski paket ponuja naslednjih pet atomskih spremenljivk:

  • AtomicInteger
  • AtomicLong
  • AtomicBoolean
  • AtomicIntegerArray
  • AtomicLongArray

Potreba po atomski spremenljivki

Oglejmo si naslednjo kodo.

java indeks od

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

Zgornji program daje pričakovan rezultat, če se izvaja v enonitnem okolju. Večnitno okolje lahko privede do nepričakovanih rezultatov. Razlog za to je, da ko dve ali več niti poskuša posodobiti vrednost hkrati, se morda ne bo pravilno posodobila.

Java ponuja dva rešitve za premagovanje te težave:

  • Z uporabo zaklepanja in sinhronizacije
  • Z uporabo atomske spremenljivke

Ustvarimo program Java in uporabimo atomsko spremenljivko, da premagamo težavo.

Z uporabo atomske spremenljivke

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

Sinhronizirano vs. Atomic vs. Hlapljivo

Sinhronizirano Atomsko Hlapljivo
Velja le za metode. Velja le za spremenljivke. Velja tudi samo za spremenljivke.
Zagotavlja vidljivost skupaj z atomičnostjo. Zagotavlja tudi vidljivost skupaj z atomičnostjo. Zagotavlja vidljivost, ne atomičnosti.
Enako ne moremo doseči. Enako ne moremo doseči. Shranjuje v RAM, zato je dostop do spremenljivk hiter. Ne zagotavlja pa varnosti niti in sinhronizacije.
Lahko se izvaja kot sinhroniziran blok ali sinhronizirana metoda. Enako ne moremo doseči. Enako ne moremo doseči.
Lahko zaklene isti objekt razreda ali drug objekt razreda. Enako ne moremo doseči. Enako ne moremo doseči.