Locking гарантирует и видимость и атомарность, volalite -- только видимость.
Взято из: http://www.askdev.ru/java/1512/volatile/ :
Данный модификатор актуален в многопоточных приложениях, гарантирует что
- Операции записи и чтения (выполняемые потоками) происходят напрямую с основной памятью. (в связи с вопросами эффективности каждый поток может использовать свою "локальную память").
- Операции записи, чтения значений длиной 64 бит происходят атомарно (данная операция может быть представлена как две 32-х битовые операции, что может вылиться в неприятности для не volatile переменных)
- с Java 1.5. При обращении к volatile переменной происходит синхронизация для всех локальных переменных потока с основной памятью
- с Java 1.5. Операции, стоящие в коде перед операцией записи в переменную volatile, должны быть выполнены раньше, то есть оптимизатор JVM не имеет права переставить их местами. Проблема напрямую связана с double-checking idiom, подробней можно посмотреть здесь
http://jeremymanson.blogspot.com/2008/05/double-checked-locking.html
http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
Безопасно использовать:
- Записываемое значение не зависит от текущего
- Не учавствует в инвариантах с другими переменными
Brian Goetz достаточно ясно сформулировал несколько паттернов безопасного использования volatile в своей статье
http://www.ibm.com/developerworks/java/library/j-jtp06197.html
http://en.wikipedia.org/wiki/Volatile_variable
Неожиданный подводный камень.
JMV обеспечивает потокобезопасноть только для атомарных операций - чтение и запись переменной.
Так что инкрмент это потоконебезопасная операция
Взято из: http://www.askdev.ru/java/1512/volatile/ :
Данный модификатор актуален в многопоточных приложениях, гарантирует что
- Операции записи и чтения (выполняемые потоками) происходят напрямую с основной памятью. (в связи с вопросами эффективности каждый поток может использовать свою "локальную память").
- Операции записи, чтения значений длиной 64 бит происходят атомарно (данная операция может быть представлена как две 32-х битовые операции, что может вылиться в неприятности для не volatile переменных)
- с Java 1.5. При обращении к volatile переменной происходит синхронизация для всех локальных переменных потока с основной памятью
- с Java 1.5. Операции, стоящие в коде перед операцией записи в переменную volatile, должны быть выполнены раньше, то есть оптимизатор JVM не имеет права переставить их местами. Проблема напрямую связана с double-checking idiom, подробней можно посмотреть здесь
http://jeremymanson.blogspot.com/2008/05/double-checked-locking.html
http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
Безопасно использовать:
- Записываемое значение не зависит от текущего
- Не учавствует в инвариантах с другими переменными
Brian Goetz достаточно ясно сформулировал несколько паттернов безопасного использования volatile в своей статье
http://www.ibm.com/developerworks/java/library/j-jtp06197.html
http://en.wikipedia.org/wiki/Volatile_variable
Неожиданный подводный камень.
JMV обеспечивает потокобезопасноть только для атомарных операций - чтение и запись переменной.
Так что инкрмент это потоконебезопасная операция
myVolatileVar++;Чтобы сделать это потокобезопасным нужно:
int temp = 0;
synchronize( myVolatileVar ) {
temp = myVolatileVar;
}
temp++;
synchronize( myVolatileVar ) {
myVolatileVar = temp;
}
Подобный код можно не писать, а пользоваться атомиками из пакета java.util.concurrent.atomic
Комментариев нет:
Отправить комментарий