【求教】关于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于引用地址的刷新,那

我觉得也没有什么问题吧,这是我的理解。。。

实在想不出个所以然,请教一下各位,有清楚的,帮忙解答一下。多谢。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值