Понимаю, что такое атомарные операции - это неделимые операции, которые могут использоваться в многопоточном режиме без синхронизации.
Например метод compareAndSet из java.util.concurrent.atomic пакета.
Но не понятно, что такое атомарность? Если атомарность - это неделимость, то приведите пример пожалуйста, чтобы стало понятно данное понятие в Java.
Необходимость координации межпроцессного взаимодействия возникает из-за того, что некоторая область памяти является общей.
Мы также знаем, что все потоки процесса используют одни и те же данные:
Простой пример общей переменной x
управляют два потока: A
и B
:
Thread A
A1. x = 5
A2. print x
Thread B
B1. x = 7
Это недетерминированный код.
Здесь нет механизма координации, поэтому мы не можем сказать, в каком порядке будут происходить эти заявления.
Некоторые возможные результаты:
5 распечатывается и является окончательным значением;
7 распечатывается и является окончательным значением; или же
5 распечатывается, а 7 является окончательным значением.
Обратите внимание, что мы не можем распечатать 7 и получить окончательное значение 5.
Нам даже не нужно иметь несколько потоков, чтобы иметь проблему с параллелизмом. Достаточно иметь прерывания в системе. Рассмотрим приложение, которое используется для подсчета наступления какого-либо события.
Мы будем хранить количество в переменной count.
Мы предоставим пользователю возможность сброса счетчика (кнопка сброса).
Каждый раз, когда мы обнаруживаем событие, мы увеличиваем count
с оператором count++;
, который выглядит как один отдельный оператор.
count++;
разбит на ряд более мелких операций. Если count
равно 4, и мы увеличиваем его:
Теперь представьте, что прерывание происходит в самый неподходящий момент. Прерывание генерируется кнопкой сброса: предполагается, что значение счетчика установлено в ноль.
Переменная count равна 5, но она должна быть 0 (или 1). Пользователь нажал кнопку сброса, но счет не был сброшен!
Если прерывание сброса произошло до чтения переменной -> 1.
Если прерывание сброса произошло после записи переменной -> 0.
Действие сброса «потеряно».
Эта проблема возникает из-за того, что инструкция count++
на самом деле состоит из трех вещей (чтение, добавление, запись) и может быть прервана в любой момент.
Когда мы выполняем операцию, которая не может быть прервана, мы говорим, что она atomic
: атомарная.
Т.е. мы хотим для определенных операций жестко установить последовательность их выполнения = атомарность.
Наиболее часто используемые атомные классы переменных в Java - AtomicInteger, AtomicLong, AtomicBoolean и AtomicReference. Эти классы представляют собой int, long, boolean и объектную ссылку соответственно, которые могут быть атомически обновлены. Основными методами, открываемыми этими классами, являются:
Потоково безопасный пример со счетчиком AtomicInteger:
public class SafeCounterWithoutLock {
private final AtomicInteger counter = new AtomicInteger(0);
public int getValue() {
return counter.get();
}
public void increment() {
while(true) {
int existingValue = getValue();
int newValue = existingValue + 1;
if(counter.compareAndSet(existingValue, newValue)) {
return;
}
}
}
}
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Уже несколько месяцев изучаю JavaВыучил основы языка, Core, коллекции, дженерики
В БД хранится timestamp, хочу преобразовать его в дату, но почему-то выводится дата понедельник 19 января 1970 годаЧто я не так делаю?
Имею код получения данных из MySQL
Всем приветЕсть задача Считать слово с клавиатуры и из символов вывести строки