Сегодня встретил такой код
class someClass {
// ...
private volatile int a;
// ...
}
Вопрос в том, что такое volatile в данном контексте?
Ответы
Ответ 1
Модификатор volatile накладывает некоторые дополнительные условия на чтение/запись переменной. Важно понять две вещи о volatile переменных:
Операции чтения/записи volatile переменной являются атомарными.
Результат операции записи значения в volatile переменную одним потоком, становитс
виден всем другим потокам, которые используют эту переменную для чтения из нее значения.
Кажется, что для человека, задающего вопрос вроде вашего, достаточно знать эти два момента.
Ответ 2
Это означает, что значение переменной будет "всегда читаться". Например, в многопоточны
приложениях один поток прочёл значение a=1, передал управление другому потоку, которы
изменил значение на a=2, потом управление вернулось. Так вот, без volatile значение a у первого потока будет 1, т.к. первый поток "помнит", что a=1, с volatile - 2, т.к. первый поток снова прочтет значение и получит уже измененное.
Ответ 3
у переменной есть мастер копия плюс по копии на каждую нить,
чьл её используют. Мастер копия синкронизируется с локальной
копией нити при входе/выходи в/из блока synchronized.
Иногда, например, пустой блок synchronized(lock){} имеет смысл.
у переменных с модификатором volatile локальных копий нет.
Все нити работают с мастер копией.
Ответ 4
Вот какое определение дается в статье «Многопоточность Java» на сайте http://alfalavista.ru.
Определение переменной с ключевым словом volatile означает, что
значение этой переменной может изменяться другими потоками. Чтобы
понять, что делает volatile, полезно разобраться, как потоки
обрабатывают обычные переменные.
В целях повышения производительности спецификация языка Java допускает
сохранение в JRE локальной копии переменной для каждого потока,
который на нее ссылается. Такие "локальные" копии переменных
напоминают кэш и помогают потоку избежать обращения к главной памяти
каждый раз, когда требуется получить значение переменной. При запуске
двух потоков один из них считывает переменную A как 5, а второй ― как
10. Если значение переменной А изменилось с 5 на 10, то первый поток не узнае
об изменении и будет хранить неправильное значение A. Но
если переменная А помечена как volatile, то когда бы поток не считывал
значение A, он будет обращаться к главной копии A и считывать ее
текущее значение. Локальный кэш потока имеет смысл в том случае, если
переменные в ваших приложениях не будут изменяться извне.
Если переменная объявлена как volatile, это означает, что она может изменятьс
разными потоками. Естественно ожидать, что JRE обеспечит ту или иную форму синхронизаци
таких volatile-переменных. JRE действительно неявно обеспечивает синхронизацию при доступе к volatile-переменным, но с одной очень большой оговоркой: чтение volatile-переменной и запись в volatile-переменную синхронизированы, а неатомарные операции ― нет.
Ответ 5
для объектным ссылок volatile можно не писать. я прав?
Например, когда мы в многопоточном приложении используем паттерн Синглтон в которо
применяем синхронизацию и хотим чтобы синхронизация осуществлялась только один раз при инициализации объекта, а не каждый раз, когда мы вызываем getInstance(), тогда модификатора volatile используем для объектной ссылки:
public class Singleton {
private static volatile Singleton instance;
private Singleton(){
}
public static Singleton getInstance() {
if (instance == null) {
synchronized(Singleton.class) {
if (instance == null)
instance = new Singleton();
}
}
return instance;
}
}
Ответ 6
volatile - буквально означает летучий, непостоянный, изменчивый
в контексте программирования это означает, что значение переменной может неожиданн
изменяться, поэтому не стоит полагаться на значения этой переменной, например, если в коде написано:
private volatile int i;
// через некоторое время
i=0;
while(i < 10) {
//blah-blah
i++;
}
это не означает, что цикл точно завершится через 10 шагов...
вполне может случиться, что в ходе выполнения цикла значение volatile переменно
будет неожиданным образом меняться (а может и не будет меняться)...
Ответ 7
volatile - говорит потоку что переменная может меняться, и информирует поток о необходимост
обращаться к последней версии, а не к хешированной копии и своевременно распространять изменения.
A "volatile" data member informs a thread, both to get the latest value for the variable (instead of using a cached copy) and to write all updates to the variable as they occur.
Комментариев нет:
Отправить комментарий