Java并发-volatile

volatile是Java并发编程中一个很重要的成员,可以把它理解为一个轻量级的synchronized

volatile的作用有两个:

  1. 保证变量的内存可见性
  2. 防止指令重排序

保证变量的内存可见性

由于每个线程都有自己的本地线程缓存,当操作主内存中的数据时,会从主内存中复制数据到本地线程缓存中再进行操作。在多线程环境下,如果多个线程同时操作主内存中的同一块内存,就会造成多个线程间的数据不一致。

cpu采用一种缓存一致性协议(IMEI)来保证各个线程间缓存的一致性。

  • 对volatile变量读写时,会触发cpu立即将本地线程缓存写回到主内存。
  • 对volatile变量写入时,会导致其他线程缓存行失效,从而强制其他线程再次读取该变量时,从主内存中获取

通过以上两个规则,就可以保证在多线程环境下,每次读取到的数据都是最新一次写入都数据。

发展指令重排序

指令重排序发生在编译器和cpu执行器,是一种提高cpu执行效率的手段。在单线程环境下,JMM能够保证被重排序后的指令执行结果的最终一致性,但并不能保证多线程环境下最终结果的正确性,这就需要进行同步处理。

同步的方法有两种,一种是加锁,保证复杂操作的原子性,一种是volatile修改变量,保证单个变量读写的原子性。

以下面一段代码为例

private Singleton singleton;

....
int a  = 1;
singletion = new Singleton();
int b = 2;

在没有volatalie修饰时,代码中的三个操作有可能会被乱序执行,同时,由于singleton = new Singleton();是一个复合操作,真正的执行顺序有可能更加乱序,那么,假如 int a = 1会影响singleton对象的正确性,如果被cpu乱序执行,int a = 1 出现在来singleton = new Singleton()的后面,就会出现错误。

如果singleton被声明为volatile,那么,singleton = new Singleton()这段代码的乱序优化并不会收到影响,而是会禁止singleton = new Singleton()与其前后代码的乱序优化,也就是保证volatile变量的乱序优化不会与其他代码的乱序优化混淆在一起。

总结

volatile变量的读写可以看成是对单个变量读写对同步处理;
对一个volatile变量对读总能看到它对最后一次写;
对单个volatile变量对读写具有原子性;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值