Класс AtomicReference
Класс AtomicReference из пакета java.util.concurrent.atomic
представляет собой контейнер для хранения ссылки на объект,
операции над которой выполняются атомарно. Это означает,
что чтение и запись значения происходят как единая
неделимая операция, и другие потоки не могут увидеть
промежуточное состояние. Класс параметризуется типом
хранимого объекта, например AtomicReference<String>
или AtomicReference<Integer>. В конструктор можно
передать начальное значение, либо создать ссылку с
нулевым значением. Основные методы позволяют получить
текущее значение, установить новое, сравнить и установить
значение за одну атомарную операцию.
Синтаксис
AtomicReference<Type> ref = new AtomicReference<>();
AtomicReference<Type> ref = new AtomicReference<>(initialValue);
Основные методы
Метод get возвращает текущее значение ссылки.
Метод set устанавливает новое значение.
Метод compareAndSet принимает ожидаемое значение
и новое значение: если текущее значение совпадает с
ожидаемым, оно заменяется на новое и возвращается
true, иначе возвращается false.
Метод getAndSet устанавливает новое значение
и возвращает предыдущее.
Пример
Давайте создадим атомарную ссылку на строку и выведем её текущее значение:
import java.util.concurrent.atomic.AtomicReference;
public class Main
{
public static void main(String[] args)
{
AtomicReference<String> ref = new AtomicReference<>("abcde");
System.out.println(ref.get());
}
}
Результат выполнения кода:
"abcde"
Пример
Давайте изменим значение ссылки с помощью метода set:
import java.util.concurrent.atomic.AtomicReference;
public class Main
{
public static void main(String[] args)
{
AtomicReference<String> ref = new AtomicReference<>("abcde");
ref.set("12345");
System.out.println(ref.get());
}
}
Результат выполнения кода:
"12345"
Пример
Давайте выполним атомарную замену значения
с помощью метода compareAndSet:
import java.util.concurrent.atomic.AtomicReference;
public class Main
{
public static void main(String[] args)
{
AtomicReference<String> ref = new AtomicReference<>("abcde");
boolean res = ref.compareAndSet("abcde", "12345");
System.out.println(res);
System.out.println(ref.get());
}
}
Результат выполнения кода:
true
"12345"
Пример
Давайте попробуем заменить значение, указав
неверное ожидаемое значение, и получим false:
import java.util.concurrent.atomic.AtomicReference;
public class Main
{
public static void main(String[] args)
{
AtomicReference<String> ref = new AtomicReference<>("abcde");
boolean res = ref.compareAndSet("wrong", "12345");
System.out.println(res);
System.out.println(ref.get());
}
}
Результат выполнения кода:
false
"abcde"
Пример
Давайте используем метод getAndSet,
чтобы получить предыдущее значение и установить новое:
import java.util.concurrent.atomic.AtomicReference;
public class Main
{
public static void main(String[] args)
{
AtomicReference<String> ref = new AtomicReference<>("abcde");
String old = ref.getAndSet("12345");
System.out.println(old);
System.out.println(ref.get());
}
}
Результат выполнения кода:
"abcde"
"12345"
Смотрите также
-
класс
AtomicInteger,
который предоставляет атомарную работу с целыми числами -
класс
AtomicBoolean,
который предоставляет атомарную работу с булевыми значениями -
класс
ThreadLocal,
который хранит отдельную копию значения для каждого потока -
ключевое слово
volatile,
которое обеспечивает видимость изменений между потоками