Почему операции над volatile переменными не атомарны?
upd: Переменная помеченная volatile является атомарной или нет?
Почему операции над volatile переменными не атомарны?
upd: Переменная помеченная volatile является атомарной или нет?
volatile обеспечивает только видимость (visibility) изменений, к атомарности он не имеет отношения. Классический пример со счетчиком: допустим есть поле volatile int i, к которому мы применим инкремент (декремент), возможна ситуация, когда два разных потока сначала проведут инкремент (декремент), а потом оба заберут результат двух инкрементов (декрементов). Такое воможно, потому что операции инкремента (декремента) не атомарны, а фактически состоят из последовательности операций, хотя и записываются одним выражением: i++ например.
volatile не обеспечивает никакой автомарности никому. volatile только означает, что значение не будет кешироваться потоком.
– tym32167
Jul 11 '20 at 15:48
volatile обеспечивает атомарность чтения и записи переменной
https://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.html
– IR42
Jul 11 '20 at 16:32
This means that changes to a volatile variable are always visible to other threads то есть атомарность в данном случае это следствие того, что значение не кешируется потоком. Другими словами, атомарность для не-volatile переменных рушится из за наличия кеша потока, который отключен для volatile переменных. Это не назначение ключевого слова, а его побочный эффект. Назначение же volatile это иметь консистентность значения среди потоков, то есть если вы записали в переменную число 10, то уверены, что все потоки, которые прочитают эту переменную, прочитают именно число 10.
– tym32167
Jul 11 '20 at 18:09
Кратко:
Мой вопрос оказался некорректным. Переменная помеченная ключевым словом volatile является атомарной для чтения и записи.
Операции над переменной помеченной volatile НЕ являются атомарными
Подробно:
Атомарная операция выглядит единой и неделимой командой процессора, которая может быть или уже выполненной или ещё невыполненной.
Если переменную сделать volatile, то запись и чтение происходит атомарно. НО если, происходит какая-то операция, например, инкримент, то уже атомарность не обеспечивается, потому что это сначала выполняется чтение(1), потом изменение(2) в локальной памяти, а затем запись(3). Такая операция не является атомарной и в неё может вклиниться поток по середине.
Источник: https://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.html
volatileэто вообще не про атомарность. – tym32167 Jul 11 '20 at 15:47