logo

Java Atomic

Javalla, atomimuuttujat ja toiminnot käytetään rinnakkain. The monisäikeinen ympäristö johtaa ongelmaan, kun samanaikaisuus on yhtenäinen. Jaettu entiteetti, kuten objektit ja muuttujat, voidaan muuttaa ohjelman suorituksen aikana. Siksi ne voivat johtaa ohjelman epäjohdonmukaisuuteen. Joten on tärkeää huolehtia jaetusta kokonaisuudesta, kun käytät samanaikaisesti. Tällaisissa tapauksissa atomi muuttuja voi olla ratkaisu siihen. Tässä osiossa keskustelemme atomiluokat, atomimuuttujat, atomioperaatiot , esimerkkien kanssa.

ohjelmistotestauksen tyypit

Ennen kuin jatkat tässä osiossa, varmista, että olet tietoinen lanka , synkronointi , ja Lukko Javassa.

Java Atomic -luokat

Java tarjoaa a java.util.concurrent.atomic paketti, jossa atomiluokat on määritelty. Atomiluokat tarjoavat a lukitsematon ja lankaturvallinen ympäristöön tai ohjelmointiin yhdellä muuttujalla. Se tukee myös atomioperaatioita. Kaikissa atomiluokissa on get()- ja set()-menetelmät, jotka toimivat haihtuvalla muuttujalla. Menetelmä toimii samalla tavalla kuin haihtuvien muuttujien lukeminen ja kirjoittaminen.

Paketti sisältää seuraavat atomiluokat:

Luokka Kuvaus
Atomic Boolean Sitä käytetään loogisen arvon päivittämiseen atomisesti.
AtomicInteger Sitä käytetään kokonaislukuarvon päivittämiseen atomisesti.
AtomicIntegerArray Int-taulukko, jossa elementit voidaan päivittää atomisesti.
AtomicIntegerFieldUpdater Heijastuspohjainen apuohjelma, joka mahdollistaa atomipäivitykset määritettyjen luokkien haihtuviin int-kenttiin.
AtomicLong Sitä käytetään pitkän arvon atomimaiseen päivittämiseen.
AtomicLongArray Pitkä taulukko, jossa elementtejä voidaan päivittää atomeittain.
AtomicLongFieldUpdater Heijastuspohjainen apuohjelma, joka mahdollistaa atomipäivitykset määritettyihin haihtuviin pitkiin määritettyjen luokkien kenttiin.
AtomicMarkableReference AtomicMarkableReference ylläpitää objektiviittausta ja merkkibittiä, joka voidaan päivittää atomisesti.
AtomicReference Objektiviittaus, joka voidaan päivittää atomisesti.
AtomicReferenceArray Joukko objektiviittauksia, joissa elementtejä voidaan päivittää atomeittain.
AtomicReferenceFieldUpdater Heijastuspohjainen apuohjelma, joka mahdollistaa atomipäivitykset määritettyjen luokkien haihtuviin viitekenttään.
AtomicStampedReference AtomicStampedReference ylläpitää objektiviittausta sekä kokonaisluku 'leimaa', joka voidaan päivittää atomisesti.
DoubleAccumulator Yksi tai useampi muuttuja, jotka yhdessä ylläpitävät käynnissä olevaa kaksoisarvoa, joka päivitetään toimitetun funktion avulla.
DoubleAdder Yksi tai useampi muuttuja, jotka yhdessä säilyttävät alun perin nollan tuplasumman.
Pitkä akku Yksi tai useampi muuttuja, jotka yhdessä ylläpitävät käynnissä olevan pitkän arvon, joka päivitetään toimitetun funktion avulla.
LongAdder Yksi tai useampi muuttuja, jotka yhdessä säilyttävät alun perin nolla pitkän summan.

Näiden luokkien objektit edustavat atomimuuttujaa int, pitkä, looginen , ja objekti viite vastaavasti. Atomiluokilla on joitain yleisiä menetelmiä, jotka ovat seuraavat:

menetelmät Kuvaus
aseta() Sitä käytetään arvon asettamiseen.
saada() Sitä käytetään nykyisen arvon saamiseen.
lazySet() Lopulta asettuu annettuun arvoon.
vertaaAndSet Atomisesti asettaa arvon annettuun päivitettyyn arvoon, jos nykyinen arvo == odotettu arvo.

Atomioperaatiot

Ne toiminnot, jotka suoritetaan aina yhdessä, tunnetaan nimellä atomioperaatiot tai atomin toimintaa . Kaikki atomioperaatiot, jotka joko suoritetaan tehokkaasti, tapahtuvat kerralla tai eivät tapahdu ollenkaan. Kolme Javan atomitoimintoihin liittyvät keskeiset käsitteet ovat seuraavat:

1. Atomicity käsittelee sitä, mitä toimintoja ja toimintoja on näkymätön Harkitse esimerkiksi seuraavaa koodinpätkää:

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

Yllä olevassa koodissa increment()- ja decrement()-suoritusten samanaikainen käyttäytyminen on määrittelemätön ja ei ennakoitavissa .

2. Näkyvyys määrittää, milloin yhden säikeen vaikutus voi olla nähty toisen toimesta. Harkitse esimerkiksi seuraavaa koodinpätkää:

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

Yllä olevassa koodissa on mahdollista, että säie T2 ei koskaan pysähdy, vaikka säie T1 on asetettu tosi. Ei myöskään, ettei säikeiden välillä olisi synkronointia.

3. Järjestys määrittää, milloin toiminnot yhdessä säikeessä tapahtuvat epäjärjestyksessä toisen säikeen suhteen.

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

Järjestys, jossa kentät a ja b näkyvät säikeessä T2, voi poiketa järjestyksestä, joka ne asetettiin säikeessä T1.

jono ja prioriteettijono javassa

Ymmärretään se esimerkin kautta.

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

Yllä olevassa koodinpätkässä olemme ilmoittaneet int-tyypin muuttujan Kreivi ja incrementCount()-metodin sisällä määritti sen arvoon 1. Siinä tapauksessa joko kaikki tapahtuvat yhdessä tai eivät tapahtuisi ollenkaan. Siksi se edustaa an atomin toiminta ja operaatio tunnetaan nimellä atomisuus .

Tarkastellaanpa toista koodinpätkää.

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

Näyttää siltä, ​​​​että se on myös atomioperaatio, mutta ei niin. Se on lineaarinen operaatio, joka koostuu kolmesta operaatiosta eli lukemisesta, muokkaamisesta ja kirjoittamisesta. Siksi se voidaan suorittaa osittain. Mutta jos käytämme yllä olevaa koodia monisäikeisessä ympäristössä, se aiheuttaa ongelman.

Oletetaan, että olemme kutsuneet yllä olevaa koodia yksisäikeisessä ympäristössä, laskenta-arvon päivitetty arvo on 2. Jos kutsumme yllä olevaa menetelmää kahdella erillisellä säikeellä, ne molemmat käyttävät muuttujaa samanaikaisesti ja päivittävät myös laskea samanaikaisesti. Tämän tilanteen välttämiseksi käytämme atomioperaatiota.

puun läpikulku

Java tukee useita atomitoimintoja, jotka ovat seuraavat:

  • Haihtuva muuttujia
  • Matalatason atomioperaatiot (vaarallinen)
  • Atomic luokat

Katsotaanpa, kuinka voimme luoda atomioperaation.

Atomimuuttuja

Atomimuuttuja mahdollistaa atomioperaation suorittamisen muuttujalle. Atomic muuttujat minimoivat synkronoinnin ja auttavat välttämään muistin johdonmukaisuusvirheet. Näin ollen se varmistaa synkronoinnin.

Atomipaketti sisältää seuraavat viisi atomimuuttujaa:

  • AtomicInteger
  • AtomicLong
  • Atomic Boolean
  • AtomicIntegerArray
  • AtomicLongArray

Atomimuuttujan tarve

Tarkastellaan seuraavaa koodia.

Oho

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

Yllä oleva ohjelma antaa odotetun tulosteen, jos se suoritetaan yksisäikeisessä ympäristössä. Monisäikeinen ympäristö voi johtaa odottamattomiin tulosteisiin. Syynä on se, että kun kaksi tai useampi säie yrittää päivittää arvoa samanaikaisesti, se ei välttämättä päivity kunnolla.

Java tarjoukset kaksi ratkaisuja tämän ongelman ratkaisemiseksi:

  • Käyttämällä lukitusta ja synkronointia
  • Käyttämällä atomimuuttujaa

Luodaan Java-ohjelma ja käytämme atomimuuttujaa ongelman voittamiseksi.

Käyttämällä Atomic Variablea

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

Synkronoitu vs. Atomic vs. Haihtuva

Synkronoitu Atomi Haihtuva
Se koskee vain menetelmiä. Se koskee vain muuttujia. Se koskee myös vain muuttujia.
Se varmistaa näkyvyyden atomisuuden ohella. Se varmistaa myös näkyvyyden atomisuuden ohella. Se takaa näkyvyyden, ei atomiteetin.
Emme voi saavuttaa samaa. Emme voi saavuttaa samaa. Se tallennetaan RAM-muistiin, joten haihtuvien muuttujien käyttö on nopeaa. Mutta se ei tarjoa lankaturvaa ja synkronointia.
Se voidaan toteuttaa synkronoituna lohkona tai synkronoituna menetelmänä. Emme voi saavuttaa samaa. Emme voi saavuttaa samaa.
Se voi lukita saman luokkaobjektin tai eri luokkaobjektin. Emme voi saavuttaa samaa. Emme voi saavuttaa samaa.