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