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



в эффективной книге Java он гласит:




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




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

631   6  

6 ответов:

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

foo = 65465498L;

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

сделать операция atomic заключается в использовании механизмов синхронизации, чтобы убедиться, что операция рассматривается из любого другого потока как одна атомарная (т. е. не разделяемая на части) операция. Это означает, что любой другой поток, как только операция становится атомарной, либо увидит значение 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;

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

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

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

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

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

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

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

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

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

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

только что нашел пост атомарные и неатомные операции чтобы быть очень полезным для меня.

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

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

когда атомарная нагрузка выполняется на общую переменную, она считывает все значение, как оно появилось в a один момент времени."

если у вас есть несколько потоков, выполняющих методы 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 В между).

Comments

    Ничего не найдено.