Параллелизм Java - класс AtomicInteger

Класс java.util.concurrent.atomic.AtomicInteger предоставляет операции с базовым значением int, которое может быть прочитано и записано атомарно, а также содержит расширенные атомарные операции. AtomicInteger поддерживает атомарные операции с базовой переменной типа int. У него есть методы получения и установки, которые работают как чтение и запись для изменчивых переменных. То есть набор имеет отношение «происходит до» с любым последующим получением той же переменной. Атомарный метод compareAndSet также имеет эти функции согласованности памяти.

Методы AtomicInteger

Ниже приводится список важных методов, доступных в классе AtomicInteger.

Sr. No. Метод и описание
1

public int addAndGet(int delta)

Атомно добавляет данное значение к текущему значению.

2

public boolean compareAndSet(int expect, int update)

Атомарно устанавливает значение для данного обновленного значения, если текущее значение совпадает с ожидаемым значением.

3

public int decrementAndGet()

Атомарно уменьшает текущее значение на единицу.

4

public double doubleValue()

Возвращает значение указанного числа в виде двойного числа.

5

public float floatValue()

Возвращает значение указанного числа в виде числа с плавающей запятой.

6

public int get()

Получает текущее значение.

7

public int getAndAdd(int delta)

Атомарно добавляет заданное значение к текущему значению.

8

public int getAndDecrement()

Атомарно уменьшает текущее значение на единицу.

9

public int getAndIncrement()

Атомарно увеличивает текущее значение на единицу.

10

public int getAndSet(int newValue)

Атомно устанавливает данное значение и возвращает старое значение.

11

public int incrementAndGet()

Атомарно увеличивает текущее значение на единицу.

12

public int intValue()

Возвращает значение указанного числа как целое число.

13

public void lazySet(int newValue)

В конце концов устанавливается на заданное значение.

14

public long longValue()

Возвращает значение указанного числа в виде длинного числа.

15

public void set(int newValue)

Устанавливается на заданное значение.

16

public String toString()

Возвращает строковое представление текущего значения.

17

public boolean weakCompareAndSet(int expect, int update)

Атомарно устанавливает значение для данного обновленного значения, если текущее значение совпадает с ожидаемым значением.

пример

Следующая программа TestThread показывает небезопасную реализацию счетчика в среде на основе потоков.

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

Это может дать следующий результат в зависимости от скорости компьютера и чередования потоков.

Вывод

Final number (should be 1000): 1000

пример

Следующая программа TestThread показывает безопасную реализацию счетчика с использованием AtomicInteger в среде на основе потоков.

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

Это даст следующий результат.

Вывод

Final number (should be 1000): 1000