2014-10-05 2 views
0

Этот Q ищет конкретные сведения о том, как именно Java делает видимым поле volatile.Как Java управляет видимостью изменчивого поля?

Ключевое слово volatile в Java используется для того, чтобы переменная «активно» была видна читателям этой переменной сразу после выполнения операции записи на ней. Это одна из форм отношений «до-отношений» - приводит к тому, что результаты записи подвергаются тому, кто имеет доступ к этой ячейке памяти этой переменной для некоторого использования. И когда используется, делает операции чтения/записи этой переменной атомарными - для long & double, а также - R/W для каждого другого типа var является атомарным уже.

Я ищу, чтобы узнать, что делает Java, чтобы сделать переменное значение видимым после операции записи?

Например .: Следующий код одного из ответов на this обсуждения:

public class Foo extends Thread { 
    private volatile boolean close = false; 
    public void run() { 
    while(!close) { 
     // do work 
    } 
    } 
    public void close() { 
    close = true; 
    // interrupt here if needed 
    } 
} 

Чтение и запись в логические литералы являются атомарными. если вызывается метод close(), это атомная операция, чтобы установить значение close как true, даже если оно не объявлено как volatile.

Что еще volatile делает в этом коде, это значит, что изменение этого значения будет видно в тот момент, когда это произойдет.

Как именно volatile достигает этого?

, отдав приоритет потокам с операциями с изменчивой переменной? если так - как, в планировании потоков или путем создания потоков с помощью операций чтения, найдите флаг, чтобы увидеть, существует ли очередь писателя? Я знаю, что «писать в поле volatile бывает - перед каждым последующим чтением этого же поля». Выбирает ли из них нити, которые имеют операцию записи на изменчивой переменной, прежде чем давать процессорное время тем потокам, которые только читаются?

Если это управляется на уровне планирования потоков (что я сомневаюсь), то выполнение потока с записью в нестабильном поле имеет больший эффект, чем кажется.

Как именно Java управляет видимостью переменных volatile?

TIA.

+1

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

+0

CPU выполняет всю работу. JVM гарантирует, что он использует правильные инструкции. –

ответ

2

Это комментарий от исходного кода OpenJDK о летучего

// ---------------------------------------------------------------------------- 
// Volatile variables demand their effects be made known to all CPU's 
// in order. Store buffers on most chips allow reads & writes to 
// reorder; the JMM's ReadAfterWrite.java test fails in -Xint mode 
// without some kind of memory barrier (i.e., it's not sufficient that 
// the interpreter does not reorder volatile references, the hardware 
// also must not reorder them). 
// 
// According to the new Java Memory Model (JMM): 
// (1) All volatiles are serialized wrt to each other. ALSO reads & 
//  writes act as aquire & release, so: 
// (2) A read cannot let unrelated NON-volatile memory refs that 
//  happen after the read float up to before the read. It's OK for 
//  non-volatile memory refs that happen before the volatile read to 
//  float down below it. 
// (3) Similar a volatile write cannot let unrelated NON-volatile 
//  memory refs that happen BEFORE the write float down to after the 
//  write. It's OK for non-volatile memory refs that happen after the 
//  volatile write to float up before it. 
// 
// We only put in barriers around volatile refs (they are expensive), 
// not _between_ memory refs (that would require us to track the 
// flavor of the previous memory refs). Requirements (2) and (3) 
// require some barriers before volatile stores and after volatile 
// loads. 

Я надеюсь, что это полезно.

+0

где вы это получили от – Roam

+0

@Roam, I работа с источниками [OpenJDK] (http://openjdk.java.net/) и этот комментарий от [hotspot's] (http://en.wikipedia.org/wiki/HotSpo t) переводчик П.С. не стесняйтесь исправить мой Английский – Kastaneda

+0

, они обычно предоставляют ссылку на источник здесь. передайте его, если не секрет или ничего – Roam

2

В соответствии с этим:

http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#volatile

Новая модель памяти в Java делает это

1) запрещающего компилятор и среду выполнения от выделения летучих переменных в регистрах.

2) не позволяет компилятору/оптимизатору изменять порядок доступа к полю из кода. Фактически, это похоже на приобретение блокировки.

3) Принуждение компилятора/среды выполнения, чтобы выгрузить переменную volatile в основную память из кеша, как только она будет записана.

4) Маркировка кеша как недействительная перед чтением изменчивого поля.

Из статьи:.

«Летучие поля специальных полей, которые используются для передачи состояния между потоками Каждого чтением летучим будет увидеть последнюю запись в том, что летучее любом потоке, в сущности, они обозначаются программистом как поля, для которых никогда не бывает приемлемым видеть «устаревшее» значение в результате кэширования или переупорядочения. Компилятору и среде выполнения запрещается выделять их в регистры. Они также должны гарантировать, что после их написания они будут выгруженные из кэша в основную память, поэтому они могут сразу стать видимыми для других потоков. Аналогично, перед чтением измененного поля кеш должен быть недействительным, так что значение в основной памяти, а не в кеше локального процессора, Также есть дополнение l ограничения на переупорядочение доступа к изменчивым переменным. "

... « Запись в энергозависимое поле имеет тот же эффект памяти, что и выпуск монитора, а чтение из энергозависимого поля имеет тот же эффект памяти, что и у монитора. Фактически, поскольку новая модель памяти накладывает более строгие ограничения на переупорядочение волатильных полевых обращений с другими доступными полями, нестабильными или нет ... »

+0

хороший ответ +1. Просто отредактируйте первое слово, напишите «По словам» вместо «ccording». – Alboz

+0

Yikes. Спасибо, исправил это. –

Смежные вопросы