Spec-Zone.ru › OpenJDK 8

Пакет java.util.concurrent.atomic

Небольшой набор классов, поддерживающих потокобезопасное программирование без блокировок на отдельных переменных.

См.: Описание

Класс Описание
AtomicBoolean

Значение типа boolean, которое может обновляться атомарно.

AtomicInteger

Значение типа int, которое может обновляться атомарно.

AtomicIntegerArray

Массив типа int, в котором элементы могут обновляться атомарно.

AtomicIntegerFieldUpdater<T>

Утилита на основе рефлексии, которая позволяет атомарно обновлять указанные volatile int поля указанных классов.

AtomicLong

Значение типа long, которое может обновляться атомарно.

AtomicLongArray

Массив типа long, в котором элементы могут обновляться атомарно.

AtomicLongFieldUpdater<T>

Утилита на основе рефлексии, которая позволяет атомарно обновлять указанные volatile long поля указанных классов.

AtomicMarkableReference<V>

Тип AtomicMarkableReference, который поддерживает ссылку на объект вместе с флагом, который может обновляться атомарно.

AtomicReference<V>

Ссылка на объект, которая может обновляться атомарно.

AtomicReferenceArray<E>

Массив ссылок на объекты, в котором элементы могут обновляться атомарно.

AtomicReferenceFieldUpdater<T,V>

Утилита на основе рефлексии, которая позволяет атомарно обновлять указанные volatile ссылки на поля указанных классов.

AtomicStampedReference<V>

Тип AtomicStampedReference, который поддерживает ссылку на объект вместе со значением "штампа", которое может обновляться атомарно.

DoubleAccumulator

Одна или несколько переменных, которые вместе поддерживают текущее double значение, обновляемое с помощью заданной функции.

DoubleAdder

Одна или несколько переменных, которые вместе поддерживают начальную сумму double.

LongAccumulator

Одна или несколько переменных, которые вместе поддерживают текущее long значение, обновляемое с помощью заданной функции.

LongAdder

Одна или несколько переменных, которые вместе поддерживают начальную сумму long.

Описание пакета java.util.concurrent.atomic

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

boolean compareAndSet(expectedValue, updateValue);

Этот метод (типы аргументов которого меняются в разных классах) атомарно устанавливает переменную в updateValue значение, если она в настоящее время содержит expectedValue, сообщая true об успехе. Классы в этом пакете также содержат методы для получения и безусловного установки значений, а также более слабую условную атомарную операцию обновления weakCompareAndSet описанную ниже.

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

Экземпляры классов AtomicBoolean, AtomicInteger, AtomicLong и AtomicReference каждый предоставляют доступ и обновления к одной переменной соответствующего типа. Каждый класс также предоставляет соответствующие вспомогательные методы для этого типа. Например, классы AtomicLong и AtomicInteger предоставляют атомарные методы инкремента. Одно из применений - генерация номеров последовательности, как в:

class Sequencer {
   private final AtomicLong sequenceNumber
     = new AtomicLong(0);
   public long next() {
     return sequenceNumber.getAndIncrement();
   }
 }

Несложно определить новые вспомогательные функции, которые, подобно getAndIncrement, применяют функцию к значению атомарно. Например, задана некоторая трансформация

long transform(long input)
напишите ваш вспомогательный метод следующим образом:
long getAndTransform(AtomicLong var) {
   long prev, next;
   do {
     prev = var.get();
     next = transform(prev);
   } while (!var.compareAndSet(prev, next));
   return prev; // return next; for transformAndGet
 }

Эффекты памяти для обращений и обновлений атомных переменных обычно следуют правилам для переменных volatile, как указано в Спецификации языка Java (17.4 Модель памяти):

  • get имеет эффекты памяти чтения переменной volatile.
  • set имеет эффекты памяти записи (присваивания) переменной volatile.
  • lazySet имеет эффекты памяти записи (присваивания) переменной volatile, за исключением того, что он допускает перестановки с последующими (но не предыдущими) действиями памяти, которые сами не накладывают ограничений на перестановки с обычными не-volatile операциями записи. Среди других контекстов использования, lazySet может применяться при обнулении, для сбора мусора, ссылки, которая больше никогда не используется.
  • weakCompareAndSet атомарно читает и условно записывает переменную, но не создает никаких порядков «происходит-раньше», так что не предоставляет никаких гарантий относительно предыдущих или последующих чтений и записей любых переменных, кроме цели weakCompareAndSet.
  • compareAndSet и все другие операции чтения и обновления, такие как getAndIncrement имеют эффекты памяти как чтения, так и записи volatile переменных.

В дополнение к классам, представляющим отдельные значения, этот пакет содержит классы Updater, которые могут использоваться для получения compareAndSet операций над любым выбранным volatile полем любого выбранного класса. AtomicReferenceFieldUpdater, AtomicIntegerFieldUpdater и AtomicLongFieldUpdater - утилиты на основе рефлексии, которые предоставляют доступ к соответствующим типам полей. Они в основном полезны в атомарных структурах данных, в которых несколько volatile полей одного узла (например, ссылки узла дерева) независимо подвергаются атомарным обновлениям. Эти классы обеспечивают большую гибкость в том, как и когда использовать атомарные обновления, ценой более неуклюжей настройки на основе рефлексии, менее удобного использования и более слабых гарантий.

Классы AtomicIntegerArray, AtomicLongArray и AtomicReferenceArray дополнительно расширяют поддержку атомарных операций до массивов этих типов. Эти классы также примечательны тем, что предоставляют volatile семантику доступа к элементам массива, которая не поддерживается для обычных массивов.

Атомарные классы также поддерживают метод weakCompareAndSet, который имеет ограниченное применение. На некоторых платформах слабая версия может быть более эффективной, чем compareAndSet в нормальном случае, но отличается тем, что любое обращение к методу weakCompareAndSet может вернуть false случайно (то есть без видимой причины). Возвращаемое значение false означает только то, что операция может быть повторена, если это необходимо, опираясь на гарантию, что многократное обращение, когда переменная содержит expectedValue и никакой другой поток также не пытается установить переменную, в конечном итоге приведет к успеху. (Такие случайные неудачи могут, например, быть вызваны эффектами конкуренции в памяти, которые не связаны с тем, равны ли ожидаемое и текущее значения.) Кроме того, weakCompareAndSet не предоставляет гарантии порядка, которые обычно необходимы для управления синхронизацией. Однако этот метод может быть полезен для обновления счетчиков и статистики, когда такие обновления не связаны с другими порядками «происходит-раньше» программы. Когда поток видит обновление атомарной переменной, вызванное weakCompareAndSet, он не обязательно видит обновления любых других переменных, произошедших до weakCompareAndSet. Это может быть приемлемо, например, при обновлении статистических данных о производительности, но редко в других случаях.

Класс AtomicMarkableReference связывает единственный булевый тип с ссылкой. Например, этот бит может использоваться внутри структуры данных, чтобы означать, что объект, на который ссылаются, логически был удален. Класс AtomicStampedReference связывает целочисленное значение со ссылкой. Это может использоваться, например, для представления номеров версий, соответствующих сериям обновлений.

Атомарные классы разработаны в первую очередь как строительные блоки для реализации неблокирующих структур данных и связанных инфраструктурных классов. Метод compareAndSet не является универсальной заменой блокировок. Он применяется только тогда, когда критические обновления объекта ограничены одной переменной.

Атомарные классы не являются универсальными заменителями java.lang.Integer и родственных классов. Они не определяют методы, такие как equals, hashCode и compareTo. (Поскольку атомарные переменные предполагаются изменяемыми, они являются плохими кандидатами для ключей хэш-таблицы.) Кроме того, классы предоставляются только для тех типов, которые обычно полезны в целевых приложениях. Например, нет атомарного класса для представления byte. В тех редких случаях, когда вы хотите это сделать, вы можете использовать AtomicInteger для хранения byte значений и выполнить соответствующее приведение типов. Вы также можете хранить числа с плавающей запятой, используя преобразования Float.floatToRawIntBits(float) и Float.intBitsToFloat(int), а числа с двойной точностью - используя преобразования Double.doubleToRawLongBits(double) и Double.longBitsToDouble(long).

С тех пор:
1.5

© 1993, 2020, Oracle and/or its affiliates. All rights reserved.
Documentation extracted from Debian's OpenJDK Development Kit package.
Licensed under the GNU General Public License, version 2, with the Classpath Exception.
Various third party code in OpenJDK is licensed under different licenses (see Debian package).
Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API