важного момент о летучем:
- синхронизация в Java можно с помощью Java уровня ключевых слов
synchronized
и volatile
.
- В Java у нас не может быть переменной
synchronized
. Использование ключевого слова synchronized
с переменной является незаконным и приведет к ошибке компиляции. Вместо использования переменной synchronized
в Java вы можете использовать переменную java volatile
, которая проинструктирует потоки JVM читать значение переменной volatile
из основной памяти и не кэшировать ее локально.
- Если переменная не разделяется между несколькими потоками, тогда нет необходимости использовать ключевое слово volatile.
source
Пример использования летучих:
public class Singleton {
private static volatile Singleton _instance; // volatile variable
public static Singleton getInstance() {
if (_instance == null) {
synchronized (Singleton.class) {
if (_instance == null)
_instance = new Singleton();
}
}
return _instance;
}
}
Мы создаем экземпляр лениво в то время первый запрос приходит.
Если мы не вносите переменную _instance
volatile
, тогда нить, которая создает экземпляр Singleton
, не может связаться с другой нитью. Поэтому, если Thread A создает экземпляр Singleton и сразу после его создания, процессор развращает и т. Д., Все остальные потоки не смогут увидеть значение _instance
как не равное null, и они будут полагать, что он по-прежнему назначен null.
Почему это происходит? Поскольку потоки чтения не блокируют и до тех пор, пока поток записи не выйдет из синхронизированного блока, память не будет синхронизирована, а значение _instance
не будет обновляться в основной памяти. С ключевым словом Volatile в Java это обрабатывается самой Java, и такие обновления будут видны всем темам чтения.
Заключение: volatile
ключевое слово также используется для передачи содержимого памяти между потоками.
Пример использования без летучих:
public class Singleton{
private static Singleton _instance; //without volatile variable
public static Singleton getInstance(){
if(_instance == null){
synchronized(Singleton.class){
if(_instance == null) _instance = new Singleton();
}
}
return _instance;
}
Код выше не поточно-.Хотя он проверяет значение экземпляра еще раз в синхронизированном блоке (по соображениям производительности), JIT-компилятор может переставить байт-код таким образом, чтобы ссылка на экземпляр была задана до того, как конструктор завершил свое выполнение. Это означает, что метод getInstance() возвращает объект, который не может быть полностью инициализирован. Чтобы обеспечить безопасность кода, ключевое слово volatile может использоваться с Java 5 для переменной экземпляра. Переменные, помеченные как volatile, становятся видимыми только для других потоков, когда конструктор объекта полностью завершил выполнение.
Source
летучее использование в Java терпеть неудачу-быстрые итераторы обычно реализованы с использованием volatile
счетчика на объекте списка.
- Когда список обновляется, счетчик увеличивается.
- Когда создается
Iterator
, текущее значение счетчика встроено в объект Iterator
.
- Когда выполняется операция
Iterator
, метод сравнивает два значения счетчика и выбрасывает ConcurrentModificationException
, если они отличаются.
Реализация отказобезопасных итераторов обычно является легкой. Они обычно полагаются на свойства структур данных конкретной реализации списка. Нет общей картины.
Я согласен - я использовал volatile по той же самой причине - отслеживание, когда закончить цикл в многопоточном приложении. – 2009-06-03 10:13:44
Этот ответ правильный, но неполный. Он опускает важное свойство `volatile`, которое поставляется с новой моделью памяти Java, определенной в JSR 133: когда поток читает переменную` volatile`, она видит не только значение, последнее записанное ей каким-то другим потоком, но и все другие записывают другие переменные, которые были видны в этом другом потоке во время «volatile» записи. См. [Этот ответ] (http://stackoverflow.com/questions/8769570/volatile-piggyback-is-this-enough-for-visiblity/8769692#8769692) и [эта ссылка] (http://www.ibm. ком/DeveloperWorks/библиотека/J-jtp03304/# 2,0). – 2013-07-18 12:32:53
Для новичков я попросил вас продемонстрировать код (пожалуйста?) – Astrobleme 2014-02-22 06:43:38