java或者其他高級語言中的volatile

我們都知道語言在編譯和執行過程中會對自身程序進行優化

如下:

public class Test{

    private static int INIT_VALUE = 0;

    private final static int MAX_VALUE = 5;

    public static void main(String[] args) {
        new Thread(() -> {
            int localValue = INIT_VALUE;
            while (localValue < MAX_VALUE){
                if(localValue != INIT_VALUE){
                    System.out.printf("The value update to [%d]",INIT_VALUE);
                    localValue = INIT_VALUE;
                }
            }
        },"READER").start();

        new Thread(() -> {
            int localValue = INIT_VALUE;
            while(localValue < MAX_VALUE){
                System.out.printf("Update the value to [%d] \n", ++localValue);
                INIT_VALUE  = localValue;
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"UPDATER").start();
}

猜猜會輸出什麼:

Update the value to [1] 
Update the value to [2] 
Update the value to [3] 
Update the value to [4] 
Update the value to [5] 

····

程序掛起

因爲2線程啓動後會更新INIT_VALUE 導致INIT_VALUE 迅速到5.

線程1 拿到的INIT_VALUE值還是0,java會內部優化此性能導致1線程 死循環

如何解決這個問題?確保INIT_VALUE能夠讀和寫分開執行並且能夠讓java忽略對該屬性的優化。就需要用到 volatile

package com.handsome.thread2study.chapter3;

/**
 * @author jiangkunli
 * @date 2020-07-01 11:47 下午
 * @description
 */
public class VolatileTest {

    private volatile static int INIT_VALUE = 0;

    private final static int MAX_VALUE = 5;

    public static void main(String[] args) {
        new Thread(() -> {
            int localValue = INIT_VALUE;
            while (localValue < MAX_VALUE){
                if(localValue != INIT_VALUE){
                    System.out.printf("The value update to [%d]",INIT_VALUE);
                    localValue = INIT_VALUE;
                }
            }
        },"READER").start();

        new Thread(() -> {
            int localValue = INIT_VALUE;
            while(localValue < MAX_VALUE){
                System.out.printf("Update the value to [%d] \n", ++localValue);
                INIT_VALUE  = localValue;
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"UPDATER").start();
    }
}




這樣執行會發現 2線程執行+後,1線程隨後就會執行updata操作,有序進行
看懂了嗎?

小結:

其實

volatile關鍵字就是將資源鎖定,同時只有一個操作來佔用源,並且是有序進行。1操作、2操作、3操作、一定不會出現 1操作 1操作無序且重複調用的情況!!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章