0

Почему операции над volatile переменными не атомарны?

upd: Переменная помеченная volatile является атомарной или нет?

Ilya Y
  • 1,002
  • Потому что volatile не делает операции переменной атомарными, поэтому они и не атомарны? – IR42 Jul 11 '20 at 13:58
  • 1
    volatile это вообще не про атомарность. – tym32167 Jul 11 '20 at 15:47
  • ну вот ниже человек скинул противоположную точку зрения и предоставил документацию – Ilya Y Jul 11 '20 at 17:22

2 Answers2

2

volatile обеспечивает только видимость (visibility) изменений, к атомарности он не имеет отношения. Классический пример со счетчиком: допустим есть поле volatile int i, к которому мы применим инкремент (декремент), возможна ситуация, когда два разных потока сначала проведут инкремент (декремент), а потом оба заберут результат двух инкрементов (декрементов). Такое воможно, потому что операции инкремента (декремента) не атомарны, а фактически состоят из последовательности операций, хотя и записываются одним выражением: i++ например.

  • Но ведь volatile обеспечивает атомарность считывание и записи double или long. – Ilya Y Jul 11 '20 at 14:10
  • Хороший вопрос. Возможно, volatile не может обеспечить атомарность таких операций как инкремент потому, что это сложная составная операция (чтение + инкремент + запись). При записи long или double производится запись первых 32-х бит, затем вторых 32-х бит (запись + запись), в таких условиях атомарность соблюдается. Еще можно ответить, что согласно Java Language Specification параграф 17.7: Writes and reads of volatile long and double values are always atomic – EvgeniiVolkov Jul 11 '20 at 14:33
  • volatile не обеспечивает никакой автомарности никому. volatile только означает, что значение не будет кешироваться потоком. – tym32167 Jul 11 '20 at 15:48
  • 1
    @tym32167 volatile обеспечивает атомарность чтения и записи переменной https://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.html – IR42 Jul 11 '20 at 16:32
  • @IR42 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
0

Кратко:

Мой вопрос оказался некорректным. Переменная помеченная ключевым словом volatile является атомарной для чтения и записи. Операции над переменной помеченной volatile НЕ являются атомарными

Подробно:

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

Если переменную сделать volatile, то запись и чтение происходит атомарно. НО если, происходит какая-то операция, например, инкримент, то уже атомарность не обеспечивается, потому что это сначала выполняется чтение(1), потом изменение(2) в локальной памяти, а затем запись(3). Такая операция не является атомарной и в неё может вклиниться поток по середине.

Источник: https://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.html

Ilya Y
  • 1,002