logo

Java Atomic

A Java, variables atòmiques i operacions utilitzat en concurrència. El multifils entorn condueix a un problema quan concurrència està unificat. L'entitat compartida, com ara objectes i variables, es pot canviar durant l'execució del programa. Per tant, poden conduir a una incoherència del programa. Per tant, és important tenir cura de l'entitat compartida mentre accediu simultàniament. En aquests casos, el variable atòmica pot ser una solució. En aquesta secció, parlarem classes atòmiques, variables atòmiques, operacions atòmiques , juntament amb exemples.

llançar en sql

Abans d'avançar en aquesta secció, assegureu-vos que en teniu coneixement fil , sincronització , i pany en Java.

Classes atòmiques de Java

Java proporciona a java.util.concurrent.atomic paquet en el qual es defineixen les classes atòmiques. Les classes atòmiques proporcionen a sense pany i sense fils entorn o programació en una sola variable. També admet operacions atòmiques. Totes les classes atòmiques tenen els mètodes get() i set() que funcionen amb la variable volàtil. El mètode funciona igual que la lectura i l'escriptura en variables volàtils.

El paquet proporciona les següents classes atòmiques:

Classe Descripció
AtomicBoolean S'utilitza per actualitzar atòmicament el valor booleà.
Atomic Integer S'utilitza per actualitzar atòmicament el valor enter.
AtomicIntegerArray Una matriu int en la qual els elements es poden actualitzar atòmicament.
AtomicIntegerFieldUpdater Una utilitat basada en la reflexió que permet actualitzacions atòmiques als camps int volàtils designats de classes designades.
AtomicLong S'utilitza per actualitzar atòmicament el valor llarg.
AtomicLongArray Una matriu llarga en què els elements es poden actualitzar atòmicament.
AtomicLongFieldUpdater Una utilitat basada en la reflexió que permet actualitzacions atòmiques a camps llargs volàtils designats de classes designades.
AtomicMarkableReference Un AtomicMarkableReference manté una referència d'objecte juntament amb un bit de marca, que es pot actualitzar atòmicament.
Referència atòmica Una referència d'objecte que es pot actualitzar atòmicament.
AtomicReferenceArray Una matriu de referències d'objectes en què els elements es poden actualitzar atòmicament.
AtomicReferenceFieldUpdater Una utilitat basada en la reflexió que permet actualitzacions atòmiques als camps de referència volàtils designats de les classes designades.
AtomicStampedReference Un AtomicStampedReference manté una referència d'objecte juntament amb un 'segell' enter, que es pot actualitzar atòmicament.
Doble Acumulador Una o més variables que juntes mantenen un valor doble en funcionament actualitzat mitjançant una funció subministrada.
DoubleAdder Una o més variables que juntes mantenen una suma doble inicialment zero.
Accumulador llarg Una o més variables que juntes mantenen un valor llarg actualitzat mitjançant una funció subministrada.
Adder llarg Una o més variables que juntes mantenen una suma llarga inicialment zero.

Els objectes d'aquestes classes representen la variable atòmica de int, llarg, booleà , i objecte referència respectivament. Les classes atòmiques tenen alguns mètodes comuns que són els següents:

Mètodes Descripció
conjunt() S'utilitza per establir el valor.
aconseguir() S'utilitza per obtenir el valor actual.
lazySet() Finalment s'estableix en el valor donat.
compareAndSet Estableix atòmicament el valor al valor actualitzat donat si el valor actual == el valor esperat.

Operacions atòmiques

Aquelles operacions que s'executen sempre juntes es coneixen com a operacions atòmiques o acció atòmica . Totes les operacions atòmiques, o bé s'executen de manera efectiva, succeeixen totes alhora o no succeeixen en absolut. Tres Els conceptes clau que s'associen amb les accions atòmiques a Java són els següents:

1. L'atomicitat tracta de quines accions i conjunts d'accions tenen invisible Per exemple, considereu el fragment de codi següent:

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

Al codi anterior, el comportament d'executar increment() i decrement() simultàniament és indefinit i no previsible .

2. La visibilitat determina quan pot ser l'efecte d'un fil vist per un altre. Per exemple, considereu el fragment de codi següent:

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

Al codi anterior, és possible que el fil T2 no s'aturi mai fins i tot després que el fil T1 s'hagi fet a vertader. A més, no és que no hi hagi sincronització entre fils.

3. L'ordenació determina quan les accions d'un fil es produeixen fora d'ordre respecte a un altre fil.

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

L'ordre en què apareixen els camps a i b al fil T2 pot ser diferent de l'ordre en què es van establir al fil T1.

for loop a bash

Entenem-ho amb un exemple.

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

Al fragment de codi anterior, hem declarat una variable de tipus int comptar i dins del mètode incrementCount() l'ha assignat a 1. En aquest cas, o bé succeeixen tots junts o no passarien en absolut. Per tant, representa un funcionament atòmic i l'operació es coneix com atomicitat .

Considerem un altre fragment de codi.

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

Sembla que també és una operació atòmica però no és així. És una operació lineal que consta de tres operacions, és a dir, llegir, modificar i escriure. Per tant, es pot executar parcialment. Però si estem utilitzant el codi anterior en un entorn multiprocés, es crea un problema.

Suposem que hem cridat el codi anterior en un entorn d'un sol fil, el valor actualitzat de count serà 2. Si cridem al mètode anterior mitjançant dos fils separats, tots dos accedeixen a la variable alhora i també actualitzen el valor de comptar simultàniament. Per evitar aquesta situació, utilitzem el funcionament atòmic.

codi de nombre aleatori c

Java admet diversos tipus d'accions atòmiques, són les següents:

  • Volàtil les variables
  • Operacions atòmiques de baix nivell (insegures)
  • Classes atòmiques

Vegem com podem crear una operació atòmica.

Variable atòmica

La variable atòmica ens permet realitzar una operació atòmica sobre una variable. Les variables atòmiques minimitzen la sincronització i ajuden a evitar errors de consistència de memòria. Per tant, garanteix la sincronització.

tapa dura vs rústica

El paquet atòmic proporciona les cinc variables atòmiques següents:

  • Atomic Integer
  • AtomicLong
  • AtomicBoolean
  • AtomicIntegerArray
  • AtomicLongArray

La necessitat de la variable atòmica

Considerem el codi següent.

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

El programa anterior proporciona la sortida esperada si s'executa en un entorn d'un sol fil. Un entorn multifil pot generar resultats inesperats. El motiu que hi ha darrere és que quan dos o més fils intenten actualitzar el valor al mateix temps, és possible que no s'actualitzi correctament.

Ofertes de Java dos solucions per superar aquest problema:

  • Mitjançant el bloqueig i la sincronització
  • Utilitzant la variable atòmica

Creem un programa Java i utilitzem una variable atòmica per superar el problema.

Mitjançant l'ús de la variable atòmica

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

Sincronitzat vs. Atòmic vs. Volàtil

Sincronitzat Atòmic Volàtil
Només s'aplica als mètodes. Només s'aplica a les variables. També s'aplica només a les variables.
Assegura la visibilitat juntament amb l'atomicitat. També garanteix la visibilitat juntament amb l'atomicitat. Assegura la visibilitat, no l'atomicitat.
No podem aconseguir el mateix. No podem aconseguir el mateix. Emmagatzema a la memòria RAM, de manera que l'accés a variables volàtils és ràpid. Però no ofereix seguretat de fil ni sincronització.
Es pot implementar com un bloc sincronitzat o un mètode sincronitzat. No podem aconseguir el mateix. No podem aconseguir el mateix.
Pot bloquejar el mateix objecte de classe o un objecte de classe diferent. No podem aconseguir el mateix. No podem aconseguir el mateix.