Рубрики
Без рубрики

Что такое изменчивая переменная в Java?

Ключевое слово volatile является одним из менее известных и менее понятных ключевых слов языка Java. То… Помеченный java.

Ключевое слово volatile является одним из менее известных и менее понятных ключевых слов языка Java. Цель этой статьи – объяснить, что это такое и когда его использовать.

Архитектура памяти

Чтобы понять значение volatile , необходимо сначала понять архитектуру памяти компьютера:

Каждый процессор содержит свои собственные регистры, которые в основном являются встроенной памятью процессора. Доступ к этим регистрам и выполнение операций с переменными здесь происходит очень быстро. Каждый процессор также имеет уровни кэш-памяти. Он может быстро получить доступ к этой кэш-памяти, но не так быстро, как регистры. Наконец, есть основная память (также называемая оперативной памятью). Все процессоры могут получить доступ к этой памяти. Основная память намного больше, чем кэш-память процессора.

Как правило, когда процессору необходимо что-то прочитать из памяти, он считывает это в кэш-память своего процессора и выполняет с ним операции. Он даже может считывать его в свои регистры. Когда процессору потребуется записать его обратно в память, он сбросит свои регистры в кэш-память, и в конечном итоге эта кэш-память будет сброшена обратно в основную память.

Как правило, очистка выполняется, когда процессору необходимо освободить место для другой информации. Таким образом, кажется очевидным, что нельзя делать никаких предположений о когда произойдет этот сброс.

Видимость общих переменных

Если на компьютере установлено 2 или более процессоров, он сможет запускать несколько потоков одновременно. Это означает, что, если каждый поток захочет получить доступ к одной и той же переменной, каждый процессор будет иметь “копию” этой переменной в своей кэш-памяти, и это может привести к серьезной проблеме синхронизации.

Возьмем, к примеру, этот код:

public class MyServer implements Runnable {
    private boolean running = true;

    @Override
    public void run() {
        while (running) {
            // Do some very interesting stuff...
        }
    }

    public void stop() {
        running = false;
    }
}

Весьма вероятно, что метод stop будет вызван из другого потока, чем тот, который выполняет метод run . Если эти потоки выполняются на 2 разных процессорах, метод run не остановится до тех пор, пока процессор не сбросит кэш-память в основную память. И мы увидели, что невозможно предсказать, когда это произойдет.

В Java ключевое слово volatile явно запрашивает прямую запись переменной в основную память и, таким образом, мгновенно становится доступной для всех процессоров.

Затем код становится:

public class MyServer implements Runnable {
    private volatile boolean running = true;

    @Override
    public void run() {
        while (running) {
            // Do some very interesting stuff...
        }
    }

    public void stop() {
        running = false;
    }
}

Обратите внимание, что изменчивая переменная может быть примитивом или объектом и может быть нулевой .

Когда использовать летучие

Изменчивая переменная гарантированно будет иметь свою последнюю версию, всегда доступную на всех процессорах. Обычно он используется для флагов, которые изменяются потоком и считываются другим потоком (например, логическое значение running в предыдущем фрагменте). Глобально вы можете использовать переменную volatile , если к переменной могут обращаться несколько потоков, и вам не нужно выполнять последовательность операций атомарным способом (например, вы не должны увеличивать переменную volatile ). Если вам нужно это сделать, вам следует рассмотреть возможность использования механизма синхронизации.

Вывод

Ключевое слово volatile используется редко, возможно, потому, что в приложении JEE (или Spring) не одобряется работа с потоками, но может быть очень полезно знать его и понимать его использование. Действительно, это может сделать ваш код более безопасным и помешать вам писать алгоритмы, которые полагаются на блокировки и синхронизацию там, где это на самом деле не нужно.

Оригинал: “https://dev.to/rnowif/what-is-a-volatile-variable-in-java-35ef”