JAVA多線程-volatile關鍵字

volatile關鍵字的主要作用是使變量在多個線程間可見。

先看個例子:
先看下賬戶類:

public class Account extends Thread{

    private BigDecimal balnace = new BigDecimal("100");

   
    public void run() {

        System.out.println("開始消費");

        while(balnace.compareTo(BigDecimal.ZERO) > 0) {

        }

        System.out.println("消費線程停止");

    }


    public BigDecimal getBalnace() {

        return balnace;

    }


    public void setBalnace(BigDecimal balnace) {

        this.balnace = balnace;

    }

}

主線程類:

public class MainThread {

    public static void main(String[] args) throws InterruptedException {

        Account account = new Account();

        account.start();

        Thread.sleep(3000);

        account.setBalnace(BigDecimal.ZERO);

        System.out.println("餘額已經被設置爲0");

    }

}

看下運行結果:

我們看到當餘額設置爲0的時候,賬戶還是一直被消費,因爲程序一直在運行中,此時有人會說餘額沒有改成功,那麼我們再來驗證下,修改主類如下:

public class MainThread {


    public static void main(String[] args) throws InterruptedException {

        Account account = new Account();

        account.start();

        Thread.sleep(3000);

        account.setBalnace(BigDecimal.ZERO);

        System.out.println("餘額已經被設置爲0");

        System.out.println(account.getBalnace());

    }

}‘

看下執行結果:

我們看到打印的餘額是0,但是程序還在執行中,那這是爲什麼呢?

我們用前面線程安全與鎖中的一張圖來看下(此處把count緩存balace一樣):

這就是因爲程序爲每個線程分配了獨立的內存空間,每個線程都有自己獨立的變量副本,其實這也是爲了提供程序的性能,每次從主內存中取數據是很耗時的,然後性能提供的同時數據不一致了,這有點CAP的感覺,那有沒有辦法可以解決呢?答案是肯定,要是沒有的話,java也不會這麼被廣泛應用,這個就是volatile關鍵字,我們修改下程序accoun類:

public class Account extends Thread{

    private volatile BigDecimal balnace = new BigDecimal("100");


    public void run() {

        System.out.println("開始消費");

        while(balnace.compareTo(BigDecimal.ZERO) > 0) {

        }

        System.out.println("消費線程停止");

    }


    public BigDecimal getBalnace() {

        return balnace;

    }


    public void setBalnace(BigDecimal balnace) {

        this.balnace = balnace;

    }

}

繼續看下執行結果:

開始消費

餘額已經被設置爲0

消費線程停止

0

這時候我們看到消費線程已經停止,這是因爲volatile關鍵字的主要作用是使變量在多線程間可見,如果被volatile修飾,則當變量改變時強制線程執行引擎去主內存中讀取變量,就是多個線程間變量的可見性。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章