Перейти к содержимому

Atomicinteger java что это

  • автор:

Atomicinteger java что это

int значение, которое может быть обновлено атомарно. См. java.util.concurrent.atomic спецификация пакета для описания свойств атомарных переменных. AtomicInteger используется в приложениях, таких как атомарно постепенно увеличенные счетчики, и не может использоваться в качестве замены для Integer . Однако, этот класс действительно расширяется Number предоставить универсальный доступ инструментами и утилитами, которые имеют дело с в цифровой форме на основе классами.

Сводка конструктора

Создает новый AtomicInteger с начальным значением 0 .
Создает новый AtomicInteger с данным начальным значением.

Сводка метода

Методы

Модификатор и Тип Метод и Описание
int addAndGet(int delta)

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

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

Атомарно декременты одним текущая стоимость.
Возвращает значение конкретного количества как a double .
Возвращает значение конкретного количества как a float .
Получает текущую стоимость.
Атомарно добавляет данное значение к текущей стоимости.
Атомарно декременты одним текущая стоимость.
Атомарно инкременты одним текущая стоимость.
Атомарно наборы к данному значению и возвратам старое значение.
Атомарно инкременты одним текущая стоимость.
Возвращает значение конкретного количества как int .
В конечном счете наборы к данному значению.
Возвращает значение конкретного количества как a long .
Наборы к данному значению.
Возвращает Строковое представление текущей стоимости.

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

Методы java.lang унаследованный от класса. Число

Методы java.lang унаследованный от класса. Объект

Деталь конструктора

AtomicInteger
public AtomicInteger(int initialValue)

Создает новый AtomicInteger с данным начальным значением.

AtomicInteger
public AtomicInteger()

Создает новый AtomicInteger с начальным значением 0 .

Деталь метода

добраться
public final int get()

Получает текущую стоимость.

набор
public final void set(int newValue)

Наборы к данному значению.

lazySet
public final void lazySet(int newValue)

В конечном счете наборы к данному значению.

getAndSet
public final int getAndSet(int newValue)

Атомарно наборы к данному значению и возвратам старое значение.

compareAndSet
public final boolean compareAndSet(int expect, int update)

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

weakCompareAndSet
public final boolean weakCompareAndSet(int expect, int update)

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

getAndIncrement
public final int getAndIncrement()

Атомарно инкременты одним текущая стоимость.

getAndDecrement
public final int getAndDecrement()

Атомарно декременты одним текущая стоимость.

getAndAdd
public final int getAndAdd(int delta)

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

incrementAndGet
public final int incrementAndGet()

Атомарно инкременты одним текущая стоимость.

decrementAndGet
public final int decrementAndGet()

Атомарно декременты одним текущая стоимость.

addAndGet
public final int addAndGet(int delta)

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

toString
public String toString()

Возвращает Строковое представление текущей стоимости.

intValue
public int intValue()

Описание скопировало с класса: Number
Возвращает значение конкретного количества как int . Это может включить округление или усечение.

longValue
public long longValue()

Описание скопировало с класса: Number
Возвращает значение конкретного количества как a long . Это может включить округление или усечение.

floatValue
public float floatValue()

Описание скопировало с класса: Number
Возвращает значение конкретного количества как a float . Это может включить округление.

doubleValue
public double doubleValue()

AtomicInteger в Java

Сегодня мы рассмотрим AtomicInteger в Java. Атомарные операции выполняются в одном блоке задачи без вмешательства других операций. Атомарные операции необходимы в многопоточной среде, чтобы избежать несогласованности данных.

AtomicInteger

package com.journaldev.concurrency; public class JavaAtomic < public static void main(String[] args) throws InterruptedException < ProcessingThread pt = new ProcessingThread(); Thread t1 = new Thread(pt, "t1"); t1.start(); Thread t2 = new Thread(pt, "t2"); t2.start(); t1.join(); t2.join(); System.out.println("Processing count=" + pt.getCount()); >> class ProcessingThread implements Runnable < private int count; @Override public void run() < for (int i = 1; i < 5; i++) < processSomething(i); count++; >> public int getCount() < return this.count; >private void processSomething(int i) < // processing some job try < Thread.sleep(i * 1000); >catch (InterruptedException e) < e.printStackTrace(); >> > 

Если вы запустите вышеуказанную программу, вы заметите, что значение count варьируется между 5,6,7,8. Причина в том, что count++ не является атомарной операцией. Таким образом, к тому времени, когда один поток прочитает это значение и увеличит его на единицу, другой поток прочитает более старое значение, что приведет к неправильному результату. Чтобы решить эту проблему, нам нужно убедиться, что операция приращения счетчика является атомарной, мы можем сделать это с помощью синхронизации, но Java 5 java.util.concurrent.atomic предоставляет классы-оболочки для int и long, которые можно использовать для выполнения этой атомарной операции без использования синхронизации.

Пример Java AtomicInteger

Вот обновленная программа, которая всегда будет выводить значение счетчика как 8, потому что метод AtomicInteger incrementAndGet() атомарно увеличивает текущее значение на единицу.

package com.journaldev.concurrency; import java.util.concurrent.atomic.AtomicInteger; public class JavaAtomic < public static void main(String[] args) throws InterruptedException < ProcessingThread pt = new ProcessingThread(); Thread t1 = new Thread(pt, "t1"); t1.start(); Thread t2 = new Thread(pt, "t2"); t2.start(); t1.join(); t2.join(); System.out.println("Processing count=" + pt.getCount()); >> class ProcessingThread implements Runnable < private AtomicInteger count = new AtomicInteger(); @Override public void run() < for (int i = 1; i < 5; i++) < processSomething(i); count.incrementAndGet(); >> public int getCount() < return this.count.get(); >private void processSomething(int i) < // processing some job try < Thread.sleep(i * 1000); >catch (InterruptedException e) < e.printStackTrace(); >> > 

Преимущества использования классов Concurrency для атомарных операций заключаются в том, что нам не нужно беспокоиться о синхронизации. Это улучшает читаемость кода и снижает вероятность ошибок. Также предполагается, что классы параллелизма атомарных операций более эффективны, чем синхронизация, которая включает блокировку ресурсов.

Все права защищены. © Linux-Console.net • 2019-2024

Как устроены атомики?

Начнем с того, что такое атомики и зачем нужны. Atomic* – семейство классов из java.util.concurrent . Они предоставляют набор атомарных операций для соответствующих типов. Например с помощью методов getAndIncrement / incrementAndGet класса AtomicInteger можно делать неатомарный в обычных условиях инкремент ( i++ ).

Условно можно разделить подходы реализации большинства atomic-методов на две группы: compare-and-set и set-and-get.

Методы категории compare-and-set принимают старое значение и новое. Если переданное старое значение совпало с текущим, устанавливается новое. Обычно делегируют вызов в методы класса Unsafe , которые заменяются нативными реализациями виртуальной машины. Виртуальная машина в большинстве случаев использует атомарную операцию процессора compare-and-swap (CAS). Поэтому атомики обычно более эффективны чем стандартная дорогостоящая блокировка.

В случае set-and-get старое значение неизвестно. Поэтому нужен небольшой трюк: программа сначала считывает текущее значение, а затем записывает новое, тоже с помощью CAS, потому что запись могла успеть поменяться даже за этот шаг. Эта попытка чтения+записи повторяется в цикле, пока старое значение не совпадет и переменная не будет успешно записана.

Этот трюк называется double-checked или optimistic locking, и может быть использован и в пользовательском коде с любым способом синхронизации. Оптимистичность заключается в том, что мы надеемся что состояния гонки нет, прибегая к синхронизации только если гонка всё же случилась. Реализация оптимистичной блокировки может быть дана как отдельная задача.

Различия между atomic, volatile и synchronized в Java

Прежде всего, необходимо понять, что это ключевые слова в языке программирования Java, которые используются для обеспечения корректной работы многопоточных приложений. Они помогают обеспечить, что при одновременном доступе нескольких потоков к одному и тому же ресурсу, не возникает конфликтов и ошибок.

Например, представьте ситуацию, когда два потока пытаются увеличить значение одного и того же счетчика. Если они оба прочтут значение счетчика, увеличат его на единицу и запишут обратно, то вместо того, чтобы счетчик увеличился на два, он увеличится только на один. Это происходит из-за того, что один поток может прочитать значение счетчика до того, как другой поток успеет записать обратно увеличенное значение.

Atomic

Atomic в Java представляет собой классы в пакете java.util.concurrent.atomic, которые позволяют выполнять атомарные операции. То есть, эти операции выполняются как единое целое и не могут быть прерваны.

В примере с счетчиком можно использовать AtomicInteger. Метод incrementAndGet() этого класса атомарно увеличивает значение счетчика на один и возвращает новое значение. Таким образом, даже если два потока одновременно вызовут этот метод, счетчик корректно увеличится на два.

Volatile

Ключевое слово volatile в Java гарантирует, что значение переменной будет сразу же записано в основную память, а не в кэш процессора, и любые другие потоки будут видеть это обновленное значение.

Вернемся к примеру с счетчиком. Если объявить счетчик как volatile int, то любые изменения его значения будут сразу же записаны в основную память, и другие потоки будут видеть это новое значение. Однако это не гарантирует атомарности операций. То есть, если два потока одновременно прочитают значение счетчика, увеличат его на один и запишут обратно, проблема с увеличением счетчика только на один, а не на два, все еще останется.

Synchronized

Ключевое слово synchronized в Java используется для обозначения блоков кода или методов, которые могут быть выполнены только одним потоком в одно и то же время.

Если применить synchronized к методу увеличения счетчика, то в любой момент времени только один поток сможет выполнить этот метод. Если другой поток попытается выполнить этот метод в то же время, он будет ждать, пока первый поток не завершит работу.

В заключении стоит отметить, что выбор между atomic, volatile и synchronized зависит от конкретной ситуации. В некоторых случаях может быть достаточно использовать volatile, в других может потребоваться более строгая синхронизация с помощью synchronized или atomic.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *