Проще говоря,
статические : static
переменные связаны с классом , а не с любым объектом . Каждый экземпляр класса разделяет переменную класса, которая находится в одном фиксированном месте в памяти
volatile : Это ключевое слово применимо к переменным class и instance .
Использование энергозависимых переменных снижает риск ошибок согласованности памяти, потому что любая запись в энергозависимую переменную устанавливает отношение «случай до» с последующим чтением этой же переменной. Это означает, что изменения в энергозависимой переменной всегда видны другим потокам
Взгляните на эту статью от Javin Paul
, чтобы лучше понять переменные переменные.
При отсутствии ключевого слова volatile
значение переменной в стеке каждого потока может отличаться. Сделав переменную volatile
, все потоки получат одно и то же значение в своей рабочей памяти, и ошибок целостности памяти удалось избежать.
Здесь термин variable
может быть либо static
(класс) переменной, либо instance
(объект) переменной.
По вашему запросу:
В любом случае, значение статической переменной также будет одним значением для всех потоков, тогда почему мы должны использовать volatile?
Если мне нужна переменная instance
в моем приложении, я не могу использовать переменную static
. Даже в случае переменной static
согласованность не гарантируется из-за кеша потоков, как показано на диаграмме.
Использование volatile
переменных снижает риск ошибок согласованности памяти, потому что любая запись в энергозависимую переменную устанавливает связь «до операции» с последующим чтением этой же переменной. Это означает, что изменения в изменчивой переменной всегда видны другим потокам.
Более того, это также означает, что когда поток читает переменную volatile, он видит не только последнее изменение volatile, но также побочные эффекты кода, который привел к изменению => ошибки согласованности памяти все еще возможны с изменчивыми переменными . Чтобы избежать побочных эффектов, вы должны использовать синхронизированные переменные. Но в Java есть лучшее решение.
Использование простого атомарного доступа к переменным более эффективно, чем доступ к этим переменным через синхронизированный код
Некоторые из классов в пакете java.util.concurrent
предоставляют атомарные методы, которые не зависят от синхронизации.
Подробнее см. В этой статье элемент управления параллельным доступом высокого уровня .
Особенно взгляните на Атомные переменные .
Связанные вопросы SE:
Летучие против атомных
Летучий логический или AtomicBoolean
Разница между энергозависимой и синхронизированной в Java