Проще говоря,
static: static
переменные связаны с класса, а не с какой-либо объекта.Каждый экземпляр класса разделяет переменную класса, которая находится в одном определенном месте в памяти
volatile: Это ключевое слово применимо как класса и экземпляра переменных.
Использование летучих переменных уменьшает риск ошибок согласованности памяти, так как любая запись в летучем устанавливает переменную-происходит прежде, чем связь с последующим считывает из той же самой переменной. Это означает, что изменения в энергозависимой переменной всегда видимы для других потоков
Посмотрите на эту article по Javin Paul
понять изменчивые переменные в лучшую сторону.
В отсутствие volatile
ключевого слова, значение переменной в стеке каждого потока может быть различным. Сделав переменную как volatile
, все потоки получат одинаковое значение в своей рабочей памяти, а ошибки согласованности памяти не будут устранены.
Здесь термин variable
может быть либо переменной static
(класс), либо переменной instance
(объект).
Что касается вашего запроса:
Во всяком случае статическая переменная величина также собирается быть одно значение для всех потоков, то почему мы должны идти на летучий?
Если мне нужно переменное instance
в моем приложении, я не могу использовать переменную static
. Даже в случае переменной static
согласованность не гарантируется из-за кэша Thread, как показано на диаграмме.
Использование переменных volatile
снижает риск ошибок согласованности памяти, поскольку любая запись в изменчивую переменную устанавливает связь между событиями и последующими чтениями этой же переменной. Это означает, что изменения в изменчивой переменной всегда видны для других потоков.
Более того, это также означает, что, когда поток считывает летучий переменную, она видит не только последние изменения в летучее, но и побочные эффекты кода, которые привели к изменению =>памяти ошибки согласованности все еще возможны с изменчивыми переменными. Чтобы избежать побочных эффектов, вы должны использовать синхронизированные переменные. Но в java есть лучшее решение.
Используя простой атомный доступ к переменному является более эффективным, чем доступ к этим переменным с помощью синхронизированного кода
Некоторые из классов в пакете java.util.concurrent
обеспечивают атомные методы, которые не зависят от синхронизации.
Обратитесь к этой статье high level concurrency control за более подробной информацией.
Особенно взгляните на Atomic variables.
Связанные SE вопросы:
Volatile Vs Atomic
Volatile boolean vs AtomicBoolean
Difference between volatile and synchronized in Java
Пожалуйста, пересмотреть свой принятый ответ, так как второй ответ от @stivlo верен –
Официальное объяснение изменчивости: http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html #volatile – Vadzim