I Java, atomare variable og operationer bruges samtidig. Det flertrådet miljø fører til et problem, når samtidighed er samlet. Den delte enhed såsom objekter og variabler kan ændres under afviklingen af programmet. Derfor kan de føre til inkonsistens i programmet. Så det er vigtigt at tage sig af den delte enhed, mens du får adgang samtidig. I sådanne tilfælde vil atomvariabel kan være en løsning på det. I dette afsnit vil vi diskutere atomare klasser, atomare variable, atomar operationer , sammen med eksempler.
np.linspace
Før du går videre i dette afsnit, skal du sikre dig, at du er opmærksom på tråd , synkronisering , og låse i Java.
Java Atomic klasser
Java giver en java.util.samtidig.atomic pakke, hvori atomklasser er defineret. Atomklasserne giver en låsefri og trådsikker miljø eller programmering på en enkelt variabel. Det understøtter også atomoperationer. Alle atomklasserne har get() og set() metoderne, der virker på den flygtige variabel. Metoden fungerer på samme måde som at læse og skrive på flygtige variable.
Pakken indeholder følgende atomklasser:
Klasse | Beskrivelse |
---|---|
Atomic boolean | Det bruges til at opdatere boolesk værdi atomært. |
AtomicInteger | Det bruges til at opdatere heltalsværdien atomisk. |
AtomicIntegerArray | Et int-array, hvor elementer kan opdateres atomisk. |
AtomicIntegerFieldUpdater | Et refleksionsbaseret værktøj, der muliggør atomopdateringer til udpegede flygtige int-felter af udpegede klasser. |
AtomicLong | Det bruges til at opdatere lang værdi atomisk. |
AtomicLongArray | En lang række, hvor elementer kan opdateres atomisk. |
AtomicLongFieldUpdater | Et refleksionsbaseret hjælpeprogram, der muliggør atomopdateringer til udpegede flygtige lange felter af udpegede klasser. |
AtomicMarkableReference | En AtomicMarkableReference vedligeholder en objektreference sammen med en markbit, der kan opdateres atomisk. |
AtomicReference | En objektreference, der kan opdateres atomisk. |
AtomicReferenceArray | En række objektreferencer, hvori elementer kan opdateres atomisk. |
AtomicReferenceFieldUpdater | Et refleksionsbaseret værktøj, der muliggør atomopdateringer til udpegede flygtige referencefelter af udpegede klasser. |
AtomicStampedReference | En AtomicStampedReference vedligeholder en objektreference sammen med et heltals 'stempel', der kan opdateres atomisk. |
Dobbeltakkumulator | En eller flere variabler, der tilsammen opretholder en kørende dobbeltværdi opdateret ved hjælp af en medfølgende funktion. |
DoubleAdder | En eller flere variable, der tilsammen opretholder en initialt nul dobbeltsum. |
Lang akkumulator | En eller flere variabler, der tilsammen opretholder en løbende lang værdi opdateret ved hjælp af en medfølgende funktion. |
LongAdder | En eller flere variabler, der tilsammen opretholder en i starten nul lang sum. |
Objekter af disse klasser repræsenterer atomvariablen af int, lang, boolesk , og gøre indsigelse reference henholdsvis. Atomklasserne har nogle almindelige metoder er som følger:
Metoder | Beskrivelse |
---|---|
sæt() | Den bruges til at indstille værdien. |
få() | Det bruges til at få den aktuelle værdi. |
lazySet() | Sætter til sidst til den givne værdi. |
compareAndSet | Atomically indstiller værdien til den givne opdaterede værdi, hvis den aktuelle værdi == den forventede værdi. |
Atomiske operationer
De operationer, der altid udføres sammen, er kendt som atomare operationer eller atomar handling . Alle de atomare operationer, der enten udføres effektivt, sker alle på én gang, eller det sker slet ikke. Tre nøglebegreber, der er forbundet med atomiske handlinger i Java, er som følger:
1. Atomicitet handler om hvilke handlinger og sæt o handlinger har usynlig Overvej f.eks. følgende kodestykke:
class NoAtomicOps { long counter=0; void increment() { for(;;) { count++; } } void decrement() { for(;;) { count--; } } //other statement }
I ovenstående kode er adfærden ved at køre increment() og decrement() samtidigt udefineret og ikke forudsigelig .
2. Synlighed bestemmer, hvornår effekten af en tråd kan være set af en anden. Overvej f.eks. følgende kodestykke:
class InfiniteLoop { boolean done= false; void work() { //thread T2 read while(!done) { //do work } } void stopWork() { //thread T1 write done=true; } //statements }
I ovenstående kode er det muligt, at tråd T2 aldrig stopper, selv efter at tråd T1 er sat til sand. Heller ikke, at der ikke er nogen synkronisering mellem tråde.
3. Rækkefølge bestemmer, hvornår handlinger i en tråd forekommer i uorden i forhold til en anden 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; } }
Den rækkefølge, felterne a og b vises i tråd T2, kan afvige fra den rækkefølge, de blev sat i tråd T1.
liste til array java
Lad os forstå det gennem et eksempel.
public class AtomicExample { int count; public void incrementCount() { count=1; }
I ovenstående kodestykke har vi erklæret en variabel af typen int tælle og inde i metoden tildelte incrementCount() det til 1. I et sådant tilfælde sker enten alle sammen eller ville det slet ikke ske. Derfor repræsenterer det en atomar drift og operationen er kendt som atomicitet .
Lad os overveje et andet kodestykke.
public class AtomicExample { int count; public void incrementCount() { count=count+1; }
Det ser ud til, at det også er en atomoperation, men ikke så. Det er en lineær operation, der består af tre operationer, dvs. læse, modificere og skrive. Derfor kan den udføres delvist. Men hvis vi bruger ovenstående kode i et multi-threaded miljø, skaber det et problem.
Antag, at vi har kaldt ovenstående kode i et enkelt-trådet miljø, vil den opdaterede værdi af count være 2. Hvis vi kalder ovenstående metode af to separate tråde, får de både adgang til variablen på samme tid og opdaterer også værdien af tælle samtidigt. For at undgå denne situation bruger vi atomar drift.
java lambda
Java understøtter flere typer atomiske handlinger, er som følger:
- Flygtig variabler
- Atomoperationer på lavt niveau (usikre)
- Atomklasser
Lad os se, hvordan vi kan skabe en atomoperation.
Atomvariabel
Atomvariablen giver os mulighed for at udføre en atomoperation på en variabel. Atomvariable minimerer synkronisering og hjælper med at undgå hukommelseskonsistensfejl. Derfor sikrer det synkronisering.
tojson java
Atompakken indeholder følgende fem atomare variable:
- AtomicInteger
- AtomicLong
- Atomic boolean
- AtomicIntegerArray
- AtomicLongArray
Behovet for atomvariabel
Lad os overveje følgende kode.
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'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;>
Ovenstående program giver det forventede output, hvis det udføres i et enkelt-trådet miljø. Et miljø med flere tråde kan føre til uventet output. Årsagen bag det, at når to eller flere tråde forsøger at opdatere værdien på samme tid, så opdateres det muligvis ikke korrekt.
Java tilbyder to løsninger til at overvinde dette problem:
- Ved at bruge lås og synkronisering
- Ved at bruge atomvariabel
Lad os oprette et Java-program og bruge en atomvariabel til at overvinde problemet.
Ved at bruge 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'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;>
Synkroniseret vs. Atomic vs. Flygtig
Synkroniseret | Atomar | Flygtig |
---|---|---|
Det gælder kun for metoder. | Det gælder kun for variabler. | Det gælder også kun for variabler. |
Det sikrer synlighed sammen med atomicitet. | Det sikrer også synlighed sammen med atomicitet. | Det sikrer synlighed, ikke atomicitet. |
Vi kan ikke opnå det samme. | Vi kan ikke opnå det samme. | Det gemmer i RAM, så det er hurtigt at få adgang til flygtige variabler. Men det giver ikke tråd-sikkerhed og synkronisering. |
Det kan implementeres som en synkroniseret blok eller en synkroniseret metode. | Vi kan ikke opnå det samme. | Vi kan ikke opnå det samme. |
Det kan låse det samme klasseobjekt eller et andet klasseobjekt. | Vi kan ikke opnå det samme. | Vi kan ikke opnå det samme. |