Java, atominiai kintamieji ir operacijos naudojami vienu metu. The kelių sriegių aplinka sukelia problemą, kai sutapimas yra vieninga. Bendrinamas objektas, pvz., objektai ir kintamieji, gali būti pakeistas vykdant programą. Taigi jie gali sukelti programos nenuoseklumą. Taigi, svarbu pasirūpinti bendrinamu subjektu tuo pačiu metu pasiekiant. Tokiais atvejais, atominis kintamasis gali būti jos sprendimas. Šiame skyriuje aptarsime atominės klasės, atominiai kintamieji, atominės operacijos , kartu su pavyzdžiais.
git pridėti viską
Prieš pereidami prie šio skyriaus, įsitikinkite, kad žinote siūlas , sinchronizavimas , ir užraktas Java kalboje.
Java atominės klasės
Java numato a java.util.concurrent.atomic paketas, kuriame apibrėžtos atominės klasės. Atominės klasės suteikia a be užrakto ir saugus siūlams aplinka arba programavimas vienu kintamuoju. Jis taip pat palaiko atomines operacijas. Visos atominės klasės turi get() ir set() metodus, kurie veikia su nepastoviu kintamuoju. Metodas veikia taip pat, kaip skaitymas ir rašymas ant nepastovių kintamųjų.
Pakuotėje pateikiamos šios atominės klasės:
Klasė | apibūdinimas |
---|---|
Atominis Būlis | Jis naudojamas loginei vertei atnaujinti atomiškai. |
Atominis sveikas skaičius | Jis naudojamas sveikųjų skaičių reikšmei atnaujinti atomiškai. |
AtomicIntegerArray | Vidinis masyvas, kuriame elementai gali būti atnaujinami atomiškai. |
AtomicIntegerFieldUpdater | Refleksija pagrįsta priemonė, leidžianti atomiškai atnaujinti nurodytus kintamus nurodytų klasių int laukus. |
AtomicLong | Jis naudojamas atomiškai atnaujinti ilgą vertę. |
AtomicLongArray | Ilgas masyvas, kuriame elementai gali būti atnaujinami atomiškai. |
AtomicLongFieldUpdater | Refleksija pagrįsta programa, leidžianti atomiškai atnaujinti nurodytus nepastovius ilgus nurodytų klasių laukus. |
AtomicMarkableReference | AtomicMarkableReference palaiko objekto nuorodą kartu su žymėjimo bitu, kurį galima atnaujinti atomiškai. |
Atominė nuoroda | Objekto nuoroda, kuri gali būti atnaujinta atomiškai. |
AtomicReferenceArray | Objektų nuorodų masyvas, kuriame elementai gali būti atnaujinami atomiškai. |
AtomicReferenceFieldUpdater | Apmąstymais pagrįsta priemonė, leidžianti atomiškai atnaujinti nurodytus nepastovius nurodytų klasių atskaitos laukus. |
AtomicStampedReference | „AtomicStampedReference“ palaiko objekto nuorodą kartu su sveikojo skaičiaus „antspaudu“, kurį galima atnaujinti atomiškai. |
DoubleAccumulator | Vienas ar daugiau kintamųjų, kurie kartu palaiko veikiančią dvigubą vertę, atnaujintą naudojant pateiktą funkciją. |
DoubleAdder | Vienas ar daugiau kintamųjų, kurie kartu palaiko iš pradžių nulinę dvigubą sumą. |
Ilgas Akumuliatorius | Vienas ar daugiau kintamųjų, kurie kartu palaiko ilgalaikę vertę, atnaujintą naudojant pateiktą funkciją. |
LongAdder | Vienas ar daugiau kintamųjų, kurie kartu palaiko iš pradžių nulinę ilgąją sumą. |
Šių klasių objektai reiškia atominį kintamąjį int, ilgas, loginis , ir objektas nuoroda atitinkamai. Atominės klasės turi keletą bendrų metodų:
Metodai | apibūdinimas |
---|---|
rinkinys () | Jis naudojamas vertei nustatyti. |
gauti () | Jis naudojamas dabartinei vertei gauti. |
lazySet() | Galiausiai nustatoma nurodyta vertė. |
palygintiAndNustatyti | Atomiškai nustato reikšmę į nurodytą atnaujintą vertę, jei dabartinė reikšmė == laukiama vertė. |
Atominės operacijos
Tos operacijos, kurios visada atliekamos kartu, yra žinomos kaip atominės operacijos arba atominis veiksmas . Visos atominės operacijos arba efektyviai vykdomos, įvyksta iš karto arba nevyksta iš viso. Trys Pagrindinės sąvokos, susijusios su atominiais veiksmais Java programoje, yra šios:
1. Atomiškumas susijęs su veiksmais ir veiksmų rinkiniais nematomas Pavyzdžiui, apsvarstykite šį kodo fragmentą:
class NoAtomicOps { long counter=0; void increment() { for(;;) { count++; } } void decrement() { for(;;) { count--; } } //other statement }
Aukščiau pateiktame kode increment() ir decrement() veikimas vienu metu yra toks neapibrėžtas ir nenuspėjamas .
2. Matomumas nustato, kada gali būti vienos gijos efektas matytas kito. Pavyzdžiui, apsvarstykite šį kodo fragmentą:
class InfiniteLoop { boolean done= false; void work() { //thread T2 read while(!done) { //do work } } void stopWork() { //thread T1 write done=true; } //statements }
Aukščiau pateiktame kode gali būti, kad sriegis T2 niekada nesustos net ir po to, kai sriegis T1 bus nustatytas į teisingą. Be to, ne tai, kad tarp gijų nėra sinchronizavimo.
3. Tvarka nustato, kada veiksmai vienoje gijoje vyksta netvarkingai kitos gijos atžvilgiu.
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; } }
Laukų a ir b pateikimo tvarka T2 gijoje gali skirtis nuo tvarkos, kuri buvo nustatyta gijoje T1.
latekso šrifto dydžiai
Supraskime tai per pavyzdį.
public class AtomicExample { int count; public void incrementCount() { count=1; }
Aukščiau pateiktame kodo fragmente paskelbėme int tipo kintamąjį skaičiuoti o metodo incrementCount() viduje jį priskyrė 1. Tokiu atveju arba viskas vyksta kartu, arba neįvyks iš viso. Vadinasi, tai reiškia an atominė operacija ir operacija žinoma kaip atomiškumas .
Panagrinėkime kitą kodo fragmentą.
public class AtomicExample { int count; public void incrementCount() { count=count+1; }
Atrodo, kad tai taip pat atominė operacija, bet ne taip. Tai linijinė operacija, kurią sudaro trys operacijos, ty skaitymas, modifikavimas ir rašymas. Todėl jis gali būti vykdomas iš dalies. Bet jei mes naudojame aukščiau pateiktą kodą kelių gijų aplinkoje, tai sukuria problemą.
Tarkime, kad iškvietėme aukščiau pateiktą kodą vienos gijos aplinkoje, atnaujinta skaičiaus reikšmė bus 2. Jei iškviesime aukščiau nurodytą metodą dviem atskiromis gijomis, jie abu pasiekia kintamąjį vienu metu ir atnaujina skaičiuoti vienu metu. Norėdami išvengti šios situacijos, naudojame atominę operaciją.
linux failų sistema
„Java“ palaiko kelių tipų atominius veiksmus, kurie yra tokie:
- Nepastovus kintamieji
- Žemo lygio atominės operacijos (nesaugios)
- Atominės klasės
Pažiūrėkime, kaip galime sukurti atominę operaciją.
Atominis kintamasis
Atominis kintamasis leidžia atlikti atominę operaciją su kintamuoju. Atominiai kintamieji sumažina sinchronizavimą ir padeda išvengti atminties nuoseklumo klaidų. Taigi tai užtikrina sinchronizavimą.
shehzad poonawala
Atominiame pakete pateikiami šie penki atominiai kintamieji:
- Atominis sveikas skaičius
- AtomicLong
- Atominis Būlis
- AtomicIntegerArray
- AtomicLongArray
Atominio kintamojo poreikis
Panagrinėkime šį kodą.
Skaitiklis.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'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't achieve the same.</td> <td>We can'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't achieve the same.</td> <td>We can't achieve the same.</td> </tr> <tr> <td>It can lock the same class object or a different class object.</td> <td>We can't achieve the same.</td> <td>We can't achieve the same.</td> </tr> </table> <hr></max;></pre></max;>
Aukščiau pateikta programa suteikia laukiamą išvestį, jei ji vykdoma vienos gijos aplinkoje. Kelių gijų aplinka gali sukelti netikėtą išvestį. Priežastis yra ta, kad kai dvi ar daugiau gijų bando atnaujinti vertę tuo pačiu metu, ji gali netinkamai atnaujinti.
Java pasiūlymai du šios problemos sprendimo būdai:
- Naudojant užraktą ir sinchronizavimą
- Naudojant atominį kintamąjį
Sukurkime Java programą ir naudokite atominį kintamąjį, kad įveiktume problemą.
Naudojant atominį kintamąjį
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't achieve the same.</td> <td>We can'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't achieve the same.</td> <td>We can't achieve the same.</td> </tr> <tr> <td>It can lock the same class object or a different class object.</td> <td>We can't achieve the same.</td> <td>We can't achieve the same.</td> </tr> </table> <hr></max;>
Sinchronizuotas vs. Atominis vs. Nepastovus
Sinchronizuotas | Atominis | Nepastovus |
---|---|---|
Tai taikoma tik metodams. | Tai taikoma tik kintamiesiems. | Tai taip pat taikoma tik kintamiesiems. |
Tai užtikrina matomumą kartu su atomiškumu. | Tai taip pat užtikrina matomumą kartu su atomiškumu. | Tai užtikrina matomumą, o ne atomiškumą. |
Mes negalime pasiekti to paties. | Mes negalime pasiekti to paties. | Jis saugomas RAM, todėl prieiga prie nepastovių kintamųjų yra greita. Tačiau tai neužtikrina gijų saugumo ir sinchronizavimo. |
Jis gali būti įgyvendintas kaip sinchronizuotas blokas arba sinchronizuotas metodas. | Mes negalime pasiekti to paties. | Mes negalime pasiekti to paties. |
Jis gali užrakinti tą patį klasės objektą arba kitą klasės objektą. | Mes negalime pasiekti to paties. | Mes negalime pasiekti to paties. |