六、面试必问——volatile作用与原理

10、volatile作用与原理

    作用:
	1)、防止重排序
            实例化一个对象分为3步:
	        //1.分配对象内存空间
	        memory = allocate();
		//2.初始化对象			
		instance(memory); 
		//3.设置instance指向刚分配的内存地址,此时instance!=null			
		instance = memory; 
		其中由于2、3不存在数据依赖关系,所以2、3步骤可能会重排序,
		解决办法就是将变量设置为volatile类型。
		
	2)、实现可见性
		当多线程对同一个变量的值进行修改时,获取的结果并不是预期的值。
		为了达到线程安全。将变量设置为volatile变量时,
		JMM会把该线程对应的工作内存中的共享变量值刷新到主内存中,
		当读取一个volatile变量时,JMM会把该线程对应的工作内存置为无效,
		那么该线程将只能从主内存中重新读取共享变量,保证变量值最新。

    原理:
	在对volatile变量修饰的共享变量进行写操作的时候,会多一行汇编代码:
	    0x01a3de1d: movb $0x0,0x1104800(%esi);0x01a3de24: lock addl $0x0,(%esp);
	lock前缀的指令在多核处理器下有2个操作:
	    1)、将当前处理器缓存行的数据会写回到系统内存;
	    2)、写回内存的操作会引起在其他CPU里缓存了该内存地址的数据无效。
	lock前缀指令其实就相当于一个内存屏障(一个CPU指令),
	volatile的底层就是通过内存屏障来实现的。
	
	处理流程如下:
	    在对volatile变量进行写操作,JVM就会向处理器发送一条Lock前缀的指令,
	    将这个变量所在缓存行的数据写回到系统内存。但是就算写回到内存,
	    如果其他处理器缓存的值还是旧的,再执行计算操作就会有问题,所以在多理器下,
	    为了保证各个处理器的缓存是一致的,就会实现缓存一致性协议(MESI),每个处理器
	    通过嗅探在总线上传播的数据来检查自己缓存的值是不是过期了,当处理器发现自己
	    缓存行对应的内存地址被修改,就会将当前处理器的缓存行设置成无效状态,
	    当处理器要对这个数据进行修改操作的时候,会强制重新从系统内存里把数据
	    读到处理器缓存里。复制代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值