Java volatile 有什麼作用

在由Java語言編寫的程序中。有時候爲了提高程序的執行效率,編譯器會自己主動對其進行優化,把經常被訪問的變量緩存起來,程序在讀取這個變量的時候有可能會直接從緩存(比如寄存器)中來讀取這個值。而不會去內存中讀取。這樣做的一個優點是提高了程序的執行效率,但當遇到多線程編程時。變量的值可能由於別的線程而改變了,而該緩存的值不會相應改變,從而造成應用程序讀取的值和實際的變量值不一致。比如,在本次線程內,當讀取一個變量時,爲提高存取速度,會先把變量讀取到一個緩存中,當以後再取變量值時,就直接從緩存中取值。當變量值在本線程裏改變時,會同一時候把變量的新值複製到該緩存中,以便保持一致。
volatile是一個類型修飾符(typespecifier)。它是被設計用來修飾被不同線程訪問和改動的變量。被volatile類型定義的變量,系統每次用到它的時候都是直接從相應的內存其中提取,而不會利用緩存。在使用了volatile修飾成員變量後,全部線程在不論什麼時候看到的變量的值都是最新的。給個例子

如果不加 volatile 這裏會出現死循環


public class VolatileTest3   {

    public  static long c = 0;
    //public  volatile static long c = 0;

    public static void main(String[] args) throws InterruptedException {
        new Thread(()->{
            while (c == 0) {
                long x = c;

            }
            System.out.println("c=" + c);
        }).start();

        Thread.sleep(100);

        c = 1;
    }
}

必須要注意的是,由於volatile不能保證操作的原子性,因此,普通情況下volatile不能取代sychronized。此外,使用volatile會阻止編譯器對代碼的優化,因此會減少程序的執行效率。所以,除非迫不得已。否則。能不使用volatile。則儘量不要使用volatile。
當多個線程進行操作共享數據時,可以保證內存中的數據可見。底層原理:內存柵欄。使用volatile關鍵字修飾時,可理解爲對數據的操作都在主存中進行。

private volatile boolean flag = false;

相較於synchronized是一種較爲輕量級的同步策略。

注意:

  • volatile不具備“互斥性”
  • volatile不能保證變量的“原子性”
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章