Java并发来一发(四)volatile关键字

一、volatile特性

volatile的两点特性:禁止指令重排序、保证内存可见性。volatile不能保证原子性。

1、禁止指令重排

原理:volatile关键字通过提供内存屏障的方式来防止指令被重排序,编译器在生成字节码时,会在指令序列中插入内存屏障来禁止特定类型的处理器重排序。

volatile禁止指令重排序的一些规则:

  • 在每个volatile写操作前插入StoreStore屏障,在写操作后插入StoreLoad屏障;
  • 在每个volatile读操作前插入LoadLoad屏障,在读操作后插入LoadStore屏障;

2、保证内存可见性

原理从写指令和读指令分别看:

  • 对volatile修饰的变量写时,会使得处理器缓存会写到内存。这保证了共享内存中数据是最新的。
  • 一个处理器缓存数据回写会导致其他处理器的缓存无效。处理器使用嗅探技术,不断检测共享内存数据变化,发现数据变化的处理器缓存行会无效,强制执行缓存行填充,这保证了共享内存中的最新数据可以更新到其他处理器。

二、volatile使用场景

由于volatile能保证可见性,但无法保证原子性,因此volatile使用的场景必须满足:

  • 对变量的写操作不依赖当前值;
  • 该变量不包含在其他变量的不变式中。(如各种判断条件)

volatile使用场景举例:

1、状态标记

如下,线程1正在执行,线程2执行shutdown,利用volatile的可见性,running变量的变更可立即被线程1感知。

// 一个工作线程
class Worker implements Runnable {
	private volatile boolean running = true;
	public void run() {
		// doSomething
	}

	public void shutdown() {
		running = false;
	}
}

2、单例模式中的double check

也是利用了volatile的可见性,避免多线程同时取instance和初始化。

class Singleton{
    private volatile static Singleton instance = null;
 
    private Singleton() {
 
    }
 
    public static Singleton getInstance() {
        if(instance==null) {
            synchronized (Singleton.class) {
                if(instance==null)
                    instance = new Singleton();
            }
        }
        return instance;
    }
}

 

参考文章:

http://www.importnew.com/24082.html

 

 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值