Что означает "атомный" в программировании?
==========================================

В книге "Эффективная Java" говорится:

>  Спецификация языка гарантирует, что чтение или запись переменная является атомарной, если переменная не имеет тип `long` или `double` [JLS, 17.4.7].
> 
> 
> 

Что означает "атомный" в контексте программирования Java или программирования вообще?

 

Вот пример, потому что пример часто яснее длинного объяснения. Предположим, что `foo` является переменной типа `long`. Следующая операция не является атомной операцией:

```
foo = 65465498L;

```

Действительно, переменная записывается с использованием двух отдельных операций: первая, которая записывает первые 32 бита, и вторую, которая записывает последние 32 бита. Это означает, что другой поток может прочитать значение `foo` и увидеть промежуточное состояние. Выполнение атома операции состоит в использовании механизмов синхронизации, чтобы убедиться, что операция видна из любого другого потока в виде одиночной атомной (то есть не разделенной по частям) операции. Это означает, что любой другой поток, как только операция будет сделана атомарной, либо увидит значение `foo` перед назначением, либо после назначения. Но никогда не промежуточное значение.

Простой способ сделать это - сделать переменную изменчивой:

```
private volatile long foo;

```

Или для синхронизации каждого доступа к переменной:

```
public synchronized void setFoo(long value) {
    this.foo = value;
}

public synchronized long getFoo() {
    return this.foo;
}
// no other use of foo outside of these two methods, unless also synchronized

```

Или заменить его на AtomicLong:

```
private AtomicLong foo;

```
 

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

 

Это то, что "кажется, что остальная часть системы происходит мгновенно", и подпадает под категорию [Linearizability](http://en.wikipedia.org/wiki/Linearizability) в вычислительных процессах. Чтобы процитировать эту связанную статью далее:

>  Атомность - это гарантия изоляции от параллельных процессов. Кроме того, атомарные операции обычно имеют преемственность или неудачу определение - они либо успешно меняют состояние системы, или не имеют видимого эффекта.
> 
> 
> 

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

Ваша цитата подчеркивает, что во всех случаях этого не должно ожидать поведения.

 

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

1) В языке структурированных запросов атомная функция - это функция, которая либо завершит, либо вернется в исходное состояние, если произойдет прерывание питания или ненормальный конец.

2) В некоторых операционных системах Unix, атомарная операция - это операция, в которой никакое изменение не может происходить за время между установкой маски и получением сигнала для изменения маски.

3) В некоторых языках программирования, включая Lisp, атом является базовой единицей исполняемого кода или данных.

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

Атомный подразумевает неделимость и неприводимость, поэтому атомная операция должна выполняться полностью или вообще не выполняться.

 

Просто нашел сообщение [Atomic vs. Non-Atomic Operations](http://preshing.com/20130618/atomic-vs-non-atomic-operations/), чтобы быть очень полезным для меня.

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

 

Если у вас несколько потоков, выполняющих методы m1 и m2 в коде ниже:

```
class SomeClass {
    private int i = 0;

    public void m1() { i = 5; }
    public int m2() { return i; }
}

```

у вас есть гарантия, что любой поток, вызывающий `m2`, будет либо читать 0, либо 5.

С другой стороны, с этим кодом (где `i` длинный):

```
class SomeClass {
    private long i = 0;

    public void m1() { i = 1234567890L; }
    public long m2() { return i; }
}

```

поток, вызывающий `m2`, мог читать 0, 1234567890L или какое-либо другое случайное значение, потому что утверждение `i = 1234567890L` не гарантировано быть атомарным для `long` (JVM мог записать первые 32 бита, а последние 32 бит в двух операциях и поток может наблюдать `i` между ними).