Simultaneidade Java - classe AtomicInteger

Uma classe java.util.concurrent.atomic.AtomicInteger fornece operações no valor int subjacente que pode ser lido e gravado atomicamente e também contém operações atômicas avançadas. AtomicInteger oferece suporte a operações atômicas na variável int subjacente. Ele possui métodos get e set que funcionam como leituras e gravações em variáveis ​​voláteis. Ou seja, um conjunto tem uma relação acontece antes com qualquer obtenção subsequente na mesma variável. O método atômico compareAndSet também possui esses recursos de consistência de memória.

Métodos AtomicInteger

A seguir está a lista de métodos importantes disponíveis na classe AtomicInteger.

Sr. Não. Método e Descrição
1

public int addAndGet(int delta)

Adiciona atomicamente o valor fornecido ao valor atual.

2

public boolean compareAndSet(int expect, int update)

Define atomicamente o valor para o valor atualizado fornecido se o valor atual for igual ao valor esperado.

3

public int decrementAndGet()

Diminui atomicamente em um o valor atual.

4

public double doubleValue()

Retorna o valor do número especificado como um duplo.

5

public float floatValue()

Retorna o valor do número especificado como um float.

6

public int get()

Obtém o valor atual.

7

public int getAndAdd(int delta)

Atomicamente adiciona o valor fornecido ao valor atual.

8

public int getAndDecrement()

Diminui atomicamente em um o valor atual.

9

public int getAndIncrement()

Aumenta atomicamente em um o valor atual.

10

public int getAndSet(int newValue)

Define atomicamente o valor fornecido e retorna o valor antigo.

11

public int incrementAndGet()

Aumenta atomicamente em um o valor atual.

12

public int intValue()

Retorna o valor do número especificado como um inteiro.

13

public void lazySet(int newValue)

Eventualmente é definido com o valor fornecido.

14

public long longValue()

Retorna o valor do número especificado como um longo.

15

public void set(int newValue)

Define o valor fornecido.

16

public String toString()

Retorna a representação de String do valor atual.

17

public boolean weakCompareAndSet(int expect, int update)

Define atomicamente o valor para o valor atualizado fornecido se o valor atual for igual ao valor esperado.

Exemplo

O seguinte programa TestThread mostra uma implementação não segura de contador em ambiente baseado em thread.

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

Isso pode produzir o seguinte resultado, dependendo da velocidade do computador e da intercalação de thread.

Resultado

Final number (should be 1000): 1000

Exemplo

O seguinte programa TestThread mostra uma implementação segura de contador usando AtomicInteger em ambiente baseado em thread.

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

Isso produzirá o seguinte resultado.

Resultado

Final number (should be 1000): 1000