Volatile详解

1.Volatile 出场

最早见volatile是在单例模式中,只能大概记得防止重排这个点:

可以看到instance需要定义为volatile变量,

到底为啥?我也是一知半解,最近有时间,好好梳理下。

public class SingleInstanceA{

        private static volatile SingleInstanceA instance;

        public static SingleInstanceA getInstance(){
               if(instance == null){
                  synchronize(SingleInstanceA.class){
                    if(instance == null){
                          instance=new SingleInstanceA();
                    }    

                  }
               }

        }

}

 

2.怎么理解

从java 角度,我一直不能理解这个词,总觉得雾里看花。终于看到一篇从嵌入式/C++角度的文章, 恍然大悟。

C语言丨深入理解volatile关键字

文章中是这么描述的:

1.原理作用

Volatile意思是“易变的”,应该解释为“直接存取原始内存地址”比较合适。“易变”是因为外在因素引起的,像多线程,中断等。

C语言书籍这样定义volatile关键字:

volatile提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,告诉编译器对该变量不做优化,都会直接从变量内存地址中读取数据,从而可以提供对特殊地址的稳定访问。

如果没有volatile关键字,则编译器可能优化读取和存储,可能暂时使用寄存器中的值,如果这个变量由别的程序更新了的话,将出现不一致的现象。(简洁的说就是:volatile关键词影响编译器编译的结果,用volatile声明的变量表示该变量随时可能发生变化,与该变量有关的运算,不要进行编译优化,以免出错)

简单来说,volatile 告诉 编译器,不要重排指令,每次读取都要去主内存(变量内存地址)中取,不要用当前线程的本地内存(寄存器)。

因此可以保证 volatile的变量修改对于其他线程可见。

SO  可见性保证了。

因为不重排 = 编译器不重排 +处理器不重排

 让volatile 不重排,所以设计者们 设计了 一个叫屏障( StoreLoad,LoadLoad,LoadStore)的东西来实现(一个指令类型,跟setnx没什么差别)

针对volatile 变量的读和写设计了一套屏障的规则,保证了变量的前后的指令也是有序的。

so 有序了.

实际上这两种特性是因为volatile的设计和实现来保证的,(别管为什么,就是这么设计的。)

3.怎么使用

volatile 主要是用于修饰变量。

public class volatileTest{

    private volatile int arg= 1;

    public int val(){ --------线程安全,正确用法
        arg=2
    }

    public int increase(){ --------线程不安全
        arg++;(arg+1)
    }

    public int val( int valb){ --------线程不安全
        arg=valb
    }   

}

volatile 代替synchronized 的场景

public class volatileA{

    private volatile int argA;

    public int val(){
        val=1;
    }
}

public class synchronizedB{

    private int argB;

    public synchronied  int val(){
        val=1;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值