【求教】關於volatile關鍵字修飾對象型和數組的問題

各位大神,請教一個問題,我今天在sonar上看到一個報警,非基礎字段不建議用volatile修飾,內容如下:

 

我看網上的解釋是volatile只是確保對象的引用地址可見。對象的成員變量是不可見的

參考:https://blog.csdn.net/u014674862/article/details/89168376(這裏寫的很好,學習了,但是這個問題沒有得到解答)

public class Test implements Runnable{

    private volatile ObjectA a;
    public Test(ObjectA a) {
        this.a = a;
    }
    public ObjectA getA() {
        return a;
    }
    public void setA(ObjectA a) {
        this.a = a;
    }
    @Override
    public void run() {
        long i = 0;
        while (a.isFlag()) {
            i++;
            System.out.println("------------------");
        }
        System.out.println("stop My Thread " + i);
    }
    public void stop() {
        a.setFlag(false);
    }
    public static void main(String[] args) throws InterruptedException {

        System.out.println(System.getProperty("java.vm.name"));
        Test test = new Test(new ObjectA());
        new Thread(test).start();
        test.stop();
        System.out.println("Main Thread " + test.getA().isFlag());
    }

    static class ObjectA {
        private boolean flag = true;

        public boolean isFlag() {
            return flag;
        }

        public void setFlag(boolean flag) {
            this.flag = flag;
        }


    }

}

輸出如下

Java HotSpot(TM) 64-Bit Server VM
Main Thread false
stop My Thread 0

發現成員變量是可見的,循環可以正常中斷。

volatile修飾非基礎類型,指的是每次刷新對象的引用。非基礎數據類型,建議用AtomiXX代替volatile。

爲什麼會有這樣的建議?實現不明白,既然成員變量是可見的,每次都分配了新的內存空間麼,空間損耗嗎?

對象型 用volatile刷新的是引用地址,不是對象內容本身。禁止了指令重排,對象內容改變happen-before於引用地址的刷新,那

我覺得也沒有什麼問題吧,這是我的理解。。。

實在想不出個所以然,請教一下各位,有清楚的,幫忙解答一下。多謝。

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