Java内存模型(四):volatile变量的特殊规则

为了便于理解的一致性,可以先查看前面的Java内存模型(二)。

volatile变量的两种特性

  1. 内存可见性
    可见性意指当一个线程修改了主内存中的变量的值,这个新值对其他线程而言是立即可以得知的。普通变量不能做到这点。
  2. 禁止指令重排序
    普通变量紧紧能保证在方法的执行过程中,所有依赖变量赋值后结果的地方能取到正确的值(当然多线程环境可能某个方法被多个线程同时执行而有违此点),而不能保证变量赋值的操作顺序与程序代码的执行顺序一致。

volatile变量的特殊规则

定义变量V、W被volatile修饰,线程T会操作变量V和W。下面用浅显的语言解释Java内存模型对其的特殊规则:
- 每次使用前从主内存读取
read、load、use必须顺序整体出现。前一个操作是load时才能use,后一个操作时use时才能load。
- 每次修改后立即同步回主内存
assign、store、write必须顺序整体出现。前一个操作是assign时才能store,后一个操作时store时才能assign。
- 避免指令重排序
如果T对V的use或者assign先于T对W的use或者assign,那么T对V的load或者write必须先于T对W的load或者assign。

性能

  • volatile的读操作性能消耗与普通变量几乎没什么差别,写操作可能会慢些,因为它有更多的规则需要遵循(在本地代码中插入许多内存屏障指令以保证处理器不乱序执行)。
  • 在某些情况下其性能确实要优于锁,但是由于虚拟机对锁实行了许多优化和消除,故难以量化会比锁快多少。

使用场景

根据volatile变量的特性,在不符合下面两个规则的情况下,仍旧需要通过加锁(隐式或者显式)来保证原子性。
1. 运算结果不依赖当前值,或者只有单一线程对变量进行写操作。
单一变量写操作很好理解。至于前半句可以举个栗子:boolean变量只有2个状态,当它的值在true或者false之间变化的时候,由true变false不能是因为它的当前值是false,或者说当前值是true时,下个值是随机的,下次最近赋值可以是true或者false。
2. 不与其他状态变量共同参与不变约束。 例如:

  volatile int i=1,j=2;
  if(i<j){//本线程读取到i、j的值时条件成立
      Thread.sleep(5000);//其他线程修改了i、j的值,使得上面的if不成立,但是下面的代码依旧会执行,这不是我们想要的
      doSomething();
  }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

stillearn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值