Concurrence Java - Classe AtomicInteger

Une classe java.util.concurrent.atomic.AtomicInteger fournit des opérations sur la valeur int sous-jacente qui peuvent être lues et écrites de manière atomique, et contient également des opérations atomiques avancées. AtomicInteger prend en charge les opérations atomiques sur la variable int sous-jacente. Il a des méthodes get et set qui fonctionnent comme des lectures et des écritures sur des variables volatiles. Autrement dit, un ensemble a une relation qui se produit avant avec tout get ultérieur sur la même variable. La méthode atomic compareAndSet possède également ces fonctionnalités de cohérence de mémoire.

Méthodes AtomicInteger

Voici la liste des méthodes importantes disponibles dans la classe AtomicInteger.

N ° Sr. Méthode et description
1

public int addAndGet(int delta)

Ajoute atomiquement la valeur donnée à la valeur actuelle.

2

public boolean compareAndSet(int expect, int update)

Définit atomiquement la valeur sur la valeur mise à jour donnée si la valeur actuelle est la même que la valeur attendue.

3

public int decrementAndGet()

Décrémente atomiquement de un la valeur actuelle.

4

public double doubleValue()

Renvoie la valeur du nombre spécifié sous forme de double.

5

public float floatValue()

Renvoie la valeur du nombre spécifié sous forme de flottant.

6

public int get()

Obtient la valeur actuelle.

sept

public int getAndAdd(int delta)

Atomiclly ajoute la valeur donnée à la valeur actuelle.

8

public int getAndDecrement()

Décrémente atomiquement de un la valeur actuelle.

9

public int getAndIncrement()

Incrémente atomiquement de un la valeur actuelle.

dix

public int getAndSet(int newValue)

Définit atomiquement la valeur donnée et renvoie l'ancienne valeur.

11

public int incrementAndGet()

Incrémente atomiquement de un la valeur actuelle.

12

public int intValue()

Renvoie la valeur du nombre spécifié sous la forme d'un entier.

13

public void lazySet(int newValue)

Définit finalement la valeur donnée.

14

public long longValue()

Renvoie la valeur du nombre spécifié sous la forme d'un long.

15

public void set(int newValue)

Définit la valeur donnée.

16

public String toString()

Renvoie la représentation String de la valeur actuelle.

17

public boolean weakCompareAndSet(int expect, int update)

Définit atomiquement la valeur sur la valeur mise à jour donnée si la valeur actuelle est la même que la valeur attendue.

Exemple

Le programme TestThread suivant montre une implémentation non sécurisée du compteur dans un environnement basé sur les threads.

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

Cela peut produire le résultat suivant en fonction de la vitesse de l'ordinateur et de l'entrelacement des threads.

Production

Final number (should be 1000): 1000

Exemple

Le programme TestThread suivant montre une implémentation sûre du compteur à l'aide d'AtomicInteger dans un environnement basé sur les threads.

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

Cela produira le résultat suivant.

Production

Final number (should be 1000): 1000