энергозависимый идентификатор в Java - PullRequest
5 голосов
/ 29 августа 2011

Я не понимаю тех немногих утверждений, которые я прочитал:

потому что доступ к энергозависимой переменной никогда не удерживает блокировку, это не подходит для случаев, когда мы хотим читать-обновлять-писать как атомарные операция (если мы не готовы «пропустить обновление»);

Что это значит, я не могу читать-обновлять-писать?

Когда я захочу использовать volatile вместо простого логического значения. В C # я помню, что я мог использовать простой статический тип bool для контроля, когда поток запускается и останавливается, но в java мне нужно использовать идентификатор "volatile":

> public class StoppableTask extends Thread {
  private volatile boolean pleaseStop;

  public void run() {
    while (!pleaseStop) {
      // do some stuff...
    }
  }

  public void tellMeToStop() {
    pleaseStop = true;
  }
}

Ответы [ 2 ]

11 голосов
/ 29 августа 2011

Предложение говорит об этом примере:

public class CounterClass {
   private volatile int counter;

   public int increment() {
       return counter++;
   }
}

Хотя counter имеет модификатор volatile, не гарантируется, что если два потока получат доступ к методу increment(), то два разных целых числавернулся.Потому что операция counter++ не является атомарной.Это get, increment, return.Возможно, что два потока вызывают increment() одновременно, и что первый поток находится в фазе get, а второй поток находится в фазе get до того, как первый поток находится в фазе increment.

Резюме: volatile не гарантирует атомарность или что-то еще.Это просто гарантирует, что при доступе к переменной вы не получите старое кэшированное значение.Но это не гарантирует никакой безопасности или атомарности нити.

2 голосов
/ 29 августа 2011

Когда я захочу использовать volatile

FWIW Брайан Гетц в Управление волатильностью перечисляет пять моделей для использования volatile:

  1. флаги состояния («канонические»)
  2. одноразовая безопасная публикация
  3. независимые наблюдения («расширение предыдущего»)
  4. паттерн «volatile bean»
  5. дешевый трюк с блокировкой чтения-записи («если число значительно превышает количество модификаций»)

Кстати, это изображение помогло мне рассчитать гарантии памяти для энергозависимых:
https://farm4.static.flickr.com/3073/3035268779_f8a9dce89d.jpg
выше, ready является летучим.Обратите внимание, что какие бы то ни было гарантии, они предназначены только для назначения, а не для чтение-обновление-запись

  • Изображение выше взято из статьи в блоге Джереми Мэнсона: What Volatile Meansв Java .

    "Первый поток пишет в ready, который будет отправителем сообщений. Второй поток читает из готовности и видит значение, записанное в него первым потоком. Поэтому он становится получателемПоскольку эта связь происходит, все содержимое памяти, видимое потоком 1, перед тем как записать его в состояние готовности, должно быть видимым для потока 2 после того, как оно прочитает значение true для состояния готовности."

...