浅谈Volatile

javavolatile
我们用一段简单的代码来开头
Java代码 收藏代码

public int i = 0;
public void increase(){
i++;
}
//getter


以上这段代码在多线程高并发的状态下能否保证所取得的i是所期待的值,答案肯定是不能的,因为对JAVA来说数据的操作是非原子性的。还有的就是部份人认为给变量i加上volatile关键字就能保证了数据操作的原子性,这显然是错误的。要记住volatile关键字只保证其可见性,也就是说当某线程修改了i的值,修改后的值对其它线程来说是立即可见的。下面我们分析通过increase()方法的字节码来解释。
Java代码 收藏代码

public void increase();
public void increase();
flags: ACC_PUBLIC
Code:
stack=3, locals=1, args_size=1
0: aload_0
1: dup
2: getfield #2 // Field i:I
5: iconst_1
6: iadd
7: putfield #2 // Field i:I
10: return
LineNumberTable:
line 5: 0
line 6: 10


编号2到7这几行指令就是i++;的,首先getfield获取到了i的值并把它压入栈顶,在这里如果i变量有加volatile关键字,则能保证i的正确性,因为无论之前有几个线程对i作了修改,它总是能够第一时间得知。如果是普通变量的话,比如A线程对变量i修改完新值后要把它重写回主内存中,其它线程要想得知i的新值要在A线程重写回主内存之后,对这感兴趣的可以看下主线程和工作线程相关的内容。 接下来就是引发问题的关键之处了,假如当A线程准备执行相加指令时,其它线程已经把i值修改了,而A线程的操作数栈顶的值已经变为脏数据了,在执行putfield后把不正确的数据同步回主内存里。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值