logo

Java Atoom

Op Java, atomaire variabelen En activiteiten gebruikt in gelijktijdigheid. De multi-threading omgeving leidt tot een probleem wanneer gelijktijdigheid is verenigd. De gedeelde entiteit, zoals objecten en variabelen, kan tijdens de uitvoering van het programma worden gewijzigd. Daarom kunnen ze leiden tot inconsistentie van het programma. Het is dus belangrijk om voor de gedeelde entiteit te zorgen terwijl u tegelijkertijd toegang heeft. In dergelijke gevallen kan de atomaire variabele kan er een oplossing voor zijn. In deze sectie zullen we bespreken atomaire klassen, atomaire variabelen, atomaire operaties , samen met voorbeelden.

tkinter-knop

Zorg ervoor dat u op de hoogte bent voordat u verdergaat met dit gedeelte draad , synchronisatie , En slot op Java.

Java-atoomklassen

Java verschaft een java.util.concurrent.atomic pakket waarin atomaire klassen worden gedefinieerd. De atomaire klassen bieden a slotvrij En draadveilig omgeving of programmeren op één enkele variabele. Het ondersteunt ook atomaire operaties. Alle atomaire klassen hebben de methoden get() en set() die werken op de vluchtige variabele. De methode werkt hetzelfde als lezen en schrijven op vluchtige variabelen.

Het pakket biedt de volgende atomaire klassen:

Klas Beschrijving
AtomicBooleaans Het wordt gebruikt om de Booleaanse waarde atomair bij te werken.
Atoomgeheel getal Het wordt gebruikt om de gehele waarde atomair bij te werken.
AtomicIntegerArray Een int-array waarin elementen atomair kunnen worden bijgewerkt.
AtomicIntegerFieldUpdater Een op reflectie gebaseerd hulpprogramma dat atomaire updates mogelijk maakt voor aangewezen vluchtige int-velden van aangewezen klassen.
AtomairLang Het wordt gebruikt om de lange waarde atomair bij te werken.
AtomicLongArray Een lange array waarin elementen atomair kunnen worden bijgewerkt.
AtomicLongFieldUpdater Een op reflectie gebaseerd hulpprogramma dat atomaire updates mogelijk maakt voor aangewezen vluchtige lange velden van aangewezen klassen.
AtomicMarkableReferentie Een AtomicMarkableReference onderhoudt een objectreferentie samen met een markeringsbit, die atomair kan worden bijgewerkt.
Atomaire referentie Een objectreferentie die atomair kan worden bijgewerkt.
AtomicReferenceArray Een array van objectreferenties waarin elementen atomair kunnen worden bijgewerkt.
AtomicReferenceFieldUpdater Een op reflectie gebaseerd hulpprogramma dat atomaire updates mogelijk maakt voor aangewezen vluchtige referentievelden van aangewezen klassen.
AtomicStampedReferentie Een AtomicStampedReference onderhoudt een objectreferentie samen met een geheel getal 'stempel', die atomair kan worden bijgewerkt.
Dubbele Accumulator Een of meer variabelen die samen een lopende dubbele waarde onderhouden, bijgewerkt met behulp van een meegeleverde functie.
DubbelAdder Een of meer variabelen die samen een dubbele som van aanvankelijk nul behouden.
Lange Accumulator Een of meer variabelen die samen een lopende lange waarde onderhouden, bijgewerkt met behulp van een meegeleverde functie.
Lange Adder Een of meer variabelen die samen een aanvankelijk nul lange som behouden.

Objecten van deze klassen vertegenwoordigen de atomaire variabele van int, lang, booleaans en bezwaar maken referentie respectievelijk. De atomaire klassen hebben enkele gemeenschappelijke methoden:

Methoden Beschrijving
set() Het wordt gebruikt om de waarde in te stellen.
krijgen() Het wordt gebruikt om de huidige waarde te verkrijgen.
luiSet() Wordt uiteindelijk ingesteld op de opgegeven waarde.
vergelijkAndSet Stelt de waarde atomair in op de opgegeven bijgewerkte waarde als de huidige waarde == de verwachte waarde.

Atomaire operaties

De bewerkingen die altijd samen worden uitgevoerd, staan ​​bekend als de atomaire operaties of atomaire actie . Alle atomaire operaties die effectief worden uitgevoerd, gebeuren allemaal tegelijk, of helemaal niet. Drie sleutelconcepten die verband houden met atomaire acties op Java zijn als volgt:

1. Atomiciteit gaat over welke acties en sets acties hebben onzichtbaar Neem bijvoorbeeld het volgende codefragment:

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

In de bovenstaande code is het gedrag van het gelijktijdig uitvoeren van increment() en decrement() hetzelfde ongedefinieerd En niet voorspelbaar .

2. Zichtbaarheid bepaalt wanneer het effect van één draad kan zijn gezien door iemand anders. Neem bijvoorbeeld het volgende codefragment:

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

In de bovenstaande code is het mogelijk dat thread T2 nooit stopt, zelfs niet nadat thread T1 is ingesteld op true. Ook niet dat er geen synchronisatie tussen threads is.

3. De volgorde bepaalt wanneer acties in de ene thread niet in de juiste volgorde plaatsvinden ten opzichte van een andere thread.

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

De volgorde waarin velden a en b verschijnen in thread T2 kan verschillen van de volgorde waarin ze zijn ingesteld in Thread T1.

YouTube downloaden met vlc

Laten we het begrijpen aan de hand van een voorbeeld.

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

In het bovenstaande codefragment hebben we een variabele van het type int gedeclareerd graaf en binnen de methode heeft incrementCount() het toegewezen aan 1. In zo'n geval gebeuren ze allemaal samen of gebeuren ze helemaal niet. Het vertegenwoordigt dus een atomaire operatie en de operatie staat bekend als atomiciteit .

Laten we een ander codefragment bekijken.

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

Het lijkt erop dat het ook een atomaire operatie is, maar dat is niet zo. Het is een lineaire bewerking die uit drie bewerkingen bestaat, namelijk lezen, wijzigen en schrijven. Daarom kan het gedeeltelijk worden uitgevoerd. Maar als we de bovenstaande code gebruiken in een omgeving met meerdere threads, ontstaat er een probleem.

Stel dat we de bovenstaande code hebben aangeroepen in een omgeving met één thread, dan is de bijgewerkte waarde van count 2. Als we de bovenstaande methode met twee afzonderlijke threads aanroepen, hebben ze allebei tegelijkertijd toegang tot de variabele en werken ze ook de waarde van tegelijkertijd tellen. Om deze situatie te voorkomen, gebruiken we atomaire operaties.

grootte van vector c++

Java ondersteunt verschillende soorten atomaire acties, deze zijn als volgt:

  • Vluchtig variabelen
  • Atomaire operaties op laag niveau (onveilig)
  • Atomaire klassen

Laten we eens kijken hoe we een atomaire operatie kunnen creëren.

Atomaire variabele

Met de atomaire variabele kunnen we een atomaire bewerking op een variabele uitvoeren. Atomaire variabelen minimaliseren de synchronisatie en helpen fouten in de geheugenconsistentie te voorkomen. Het zorgt dus voor synchronisatie.

Het atomaire pakket biedt de volgende vijf atomaire variabelen:

  • Atoomgeheel getal
  • AtomairLang
  • AtomicBooleaans
  • AtomicIntegerArray
  • AtomicLongArray

De behoefte aan atomaire variabelen

Laten we de volgende code bekijken.

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

Het bovenstaande programma geeft de verwachte output als het wordt uitgevoerd in een single-threaded omgeving. Een omgeving met meerdere threads kan tot onverwachte uitvoer leiden. De reden hierachter is dat wanneer twee of meer threads tegelijkertijd de waarde proberen bij te werken, deze mogelijk niet correct wordt bijgewerkt.

Java-retourarray

Java-aanbiedingen twee oplossingen om dit probleem op te lossen:

  • Door gebruik te maken van vergrendeling en synchronisatie
  • Door atomaire variabelen te gebruiken

Laten we een Java-programma maken en een atomaire variabele gebruiken om het probleem op te lossen.

Door atomaire variabelen te gebruiken

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

Gesynchroniseerd versus. Atomaire versus. Vluchtig

Gesynchroniseerd Atoom Vluchtig
Het geldt alleen voor methoden. Het geldt alleen voor variabelen. Het geldt ook alleen voor variabelen.
Het zorgt voor zichtbaarheid en atomiciteit. Het zorgt ook voor zichtbaarheid en atomiciteit. Het zorgt voor zichtbaarheid, niet voor atomiciteit.
Wij kunnen niet hetzelfde bereiken. Wij kunnen niet hetzelfde bereiken. Het wordt opgeslagen in het RAM, dus toegang tot vluchtige variabelen is snel. Maar het biedt geen draadveiligheid en synchronisatie.
Het kan worden geïmplementeerd als een gesynchroniseerd blok of een gesynchroniseerde methode. Wij kunnen niet hetzelfde bereiken. Wij kunnen niet hetzelfde bereiken.
Het kan hetzelfde klasseobject of een ander klasseobject vergrendelen. Wij kunnen niet hetzelfde bereiken. Wij kunnen niet hetzelfde bereiken.