Concurrencia de Java - Clase AtomicInteger

Una clase java.util.concurrent.atomic.AtomicInteger proporciona operaciones sobre el valor int subyacente que se puede leer y escribir de forma atómica, y también contiene operaciones atómicas avanzadas. AtomicInteger admite operaciones atómicas en la variable int subyacente. Tiene métodos get y set que funcionan como lectura y escritura en variables volátiles. Es decir, un conjunto tiene una relación de suceder antes con cualquier obtención posterior de la misma variable. El método atomic compareAndSet también tiene estas características de coherencia de memoria.

Métodos AtomicInteger

A continuación se muestra la lista de métodos importantes disponibles en la clase AtomicInteger.

No Señor. Método y descripción
1

public int addAndGet(int delta)

Agrega atómicamente el valor dado al valor actual.

2

public boolean compareAndSet(int expect, int update)

Atómicamente establece el valor en el valor actualizado dado si el valor actual es el mismo que el valor esperado.

3

public int decrementAndGet()

Disminuye atómicamente en uno el valor actual.

4

public double doubleValue()

Devuelve el valor del número especificado como doble.

5

public float floatValue()

Devuelve el valor del número especificado como flotante.

6

public int get()

Obtiene el valor actual.

7

public int getAndAdd(int delta)

Atómicamente agrega el valor dado al valor actual.

8

public int getAndDecrement()

Disminuye atómicamente en uno el valor actual.

9

public int getAndIncrement()

Incrementa atómicamente en uno el valor actual.

10

public int getAndSet(int newValue)

Atómicamente se establece en el valor dado y devuelve el valor anterior.

11

public int incrementAndGet()

Incrementa atómicamente en uno el valor actual.

12

public int intValue()

Devuelve el valor del número especificado como int.

13

public void lazySet(int newValue)

Eventualmente se establece en el valor dado.

14

public long longValue()

Devuelve el valor del número especificado como long.

15

public void set(int newValue)

Establece el valor dado.

dieciséis

public String toString()

Devuelve la representación de cadena del valor actual.

17

public boolean weakCompareAndSet(int expect, int update)

Atómicamente establece el valor en el valor actualizado dado si el valor actual es el mismo que el valor esperado.

Ejemplo

El siguiente programa TestThread muestra una implementación insegura de contador en un entorno basado en subprocesos.

public class TestThread {

   static class Counter {
      private int c = 0;

      public void increment() {
         c++;
      }

      public int value() {
         return c;
      }
   }
   
   public static void main(final String[] arguments) throws InterruptedException {
      final Counter counter = new Counter();
      
      //1000 threads
      for(int i = 0; i < 1000 ; i++) {
         
         new Thread(new Runnable() {
            
            public void run() {
               counter.increment();
            }
         }).start(); 
      }  
      Thread.sleep(6000);
      System.out.println("Final number (should be 1000): " + counter.value());
   }  
}

Esto puede producir el siguiente resultado dependiendo de la velocidad de la computadora y el entrelazado de hilos.

Salida

Final number (should be 1000): 1000

Ejemplo

El siguiente programa TestThread muestra una implementación segura de contador usando AtomicInteger en un entorno basado en subprocesos.

import java.util.concurrent.atomic.AtomicInteger;

public class TestThread {

   static class Counter {
      private AtomicInteger c = new AtomicInteger(0);

      public void increment() {
         c.getAndIncrement();
      }

      public int value() {
         return c.get();
      }
   }
   
   public static void main(final String[] arguments) throws InterruptedException {
      final Counter counter = new Counter();
      
      //1000 threads
      for(int i = 0; i < 1000 ; i++) {

         new Thread(new Runnable() {
            public void run() {
               counter.increment();
            }
         }).start(); 
      }  
      Thread.sleep(6000);
      System.out.println("Final number (should be 1000): " + counter.value());
   }
}

Esto producirá el siguiente resultado.

Salida

Final number (should be 1000): 1000