volatile关键字的作用

两个作用:

  1. 在当前的java内存模型下,线程可以把变量保存在本地内存中,比如说机器的寄存器,而不单单是在主内存中进行读写,所以有可能出现这样的情况:一个线程在主存中更改了一个变量的值,另外一个线程在本地内存中读取了这个变量值的旧值,这就造成的数据的不一致。而将变量声明为volatile则是告诉jvm这个变量是不稳定的没每次都要从主存中读取。
  2. 可以防止指令的重排。

看个例子:多线程下单例模式的线程安全

	public class Singleton {

    	private volatile static Singleton uniqueInstance;

    	private Singleton() {
    	}

    	public static Singleton getUniqueInstance() {
       		//先判断对象是否已经实例过,没有实例化过才进入加锁代码
        	if (uniqueInstance == null) {
            	//类对象加锁
            	synchronized (Singleton.class) {
                	if (uniqueInstance == null) {
                   	 	uniqueInstance = new Singleton();
                	}
            	}
        	}
        	return uniqueInstance;
    	}
	}

代码中,uniqueInstance = new Singleton();分为三步执行:

  1. 在堆中为uniqueInstance 分配内存空间;
  2. 执行new Singleton()的初始化操作;
  3. 将uniqueInstance 指向对应的内存空间;

但是,jvm有指令重排的特性,即执行顺序可能变为1->3->2。假设线程1执行了1和3;此时线程2进入方法,发现uniqueInstance 不等于null,直接返回uniqueInstance,但uniqueInstance还没有初始化,就会出现线程安全的问题。使用volatile禁止指令重排便能解决此问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值