Цитата из книги "Java Threads" о ключевом слове volatile - PullRequest
3 голосов
/ 30 мая 2011

Мне просто интересно, может ли кто-нибудь объяснить значение этого:

Операции типа приращения и декремент (например, ++ и --) не может быть используется на переменную, потому что переменная эти операции являются синтаксическим сахаром для загрузки, изменения и магазина.

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

Ответы [ 5 ]

8 голосов
/ 30 мая 2011

volatile переменная только обеспечивает видимость . Это не гарантирует атомарность . Я полагаю, именно так следует понимать это утверждение.

7 голосов
/ 30 мая 2011

Я думаю, что вы берете цитату из контекста.

Конечно, ++ и -- могут применяться к переменным переменным. Они просто не будут атомными.

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

Проблема с ++ и -- заключается в том, что они могут чувствовать как атомные, тогда как на самом деле это не так.

Выполнение a = a + 1 делает (несколько) явным, что это не атомарная операция, но один может (ошибочно) думать, что a++ является атомарным.

3 голосов
/ 30 мая 2011

В спецификации языка Java нет атомарных операций для операторов ++ и --.Другими словами, когда вы пишете код следующим образом:

a++;

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

  1. Загрузите операнд в стек, используя одну из операций для load ввода данных.
  2. Дублируйте значение операнда в стеке (с целью возвратапотом).Обычно это выполняется с помощью операции dup.
  3. Увеличивает значение в стеке.Обычно выполняется с помощью операции iadd в ВМ.
  4. Возвращает значение (полученное на шаге 2).

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

Использование ключевого слова volatile позволяет другим потокам получать самое последнее значение переменной;все операции чтения переменной будут возвращать недавно обновленное значение для каждой инструкции.Например, если переменная a должна быть энергозависимой в предыдущем примере, то поток, считывающий значение a, будет видеть другие значения, если он будет читать a после инструкции 2 и после инструкции 3. Использованиеvolatile не защищает от этого сценария.Он защищает от сценария, когда несколько потоков видят несколько значений для a после инструкции 2 (например).

1 голос
/ 31 июля 2012

Volatile не гарантирует атомарность в операции, которая включает в себя несколько шагов.

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

Операции увеличения и уменьшения являются многошаговыми и, следовательно, использованиемодификатор volatile недостаточен.

0 голосов
/ 30 мая 2011

Нет - вы используете «volatile», чтобы указать, что переменная может быть изменена внешним объектом.Обычно это будет некоторый код JNI C или специальный регистр, связанный с некоторыми аппаратными средствами, такими как термометр.Java не может гарантировать, что все JVM на всех архитектурах будут способны увеличивать эти значения за один машинный цикл.Так что это не позволяет вам делать это где угодно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...