volatile java 原子_java的volatile为什么不能无法对非原子性操作生效?

展开全部

你误解了volatile的用法,volatile和原子性、非原子性没有任何关系,用volatile修饰的变量,线程在每次使用变量的时候,32313133353236313431303231363533e58685e5aeb931333431346335都会读取变量修改后的最新的值,注意,只是读取。我写了一个例子,方便你理解:public class Counter {

public volatile static int i = 0;

public static void inc() {

i++;

}

public static void main(String[] args) {

// 同时启动1000个线程,去进行i++计算,看看实际结果

for (int i = 0; i 

new Thread(new Runnable() {

@Override

public void run() {

Counter.inc();

}

}).start();

}

// 这里每次运行的值都有可能不同,可能为1000

System.out.println("运行结果:i.count=" + Counter.i);

}

}

运行结果:运行结果:i.count=965

这里的结果并不是我们所预期的1000,那么问题究竟出在哪里?

假如,现在 i = 100,线程A和线程B同时读取了 i,那么线程A和线程B中的 i 都是100。然后,线程A执行了 i++ 操作,此时 i = 101,这里注意,线程B中的 i 不会受到线程A执行完后的影响,还是等于100,线程B执行i++ 操作,此时 i = 101。

为什么线程A中的 i 不会对线程B中的 i 造成影响?

这里就涉及到内存的知识了,最开始定义的全局变量 i 是储存在主内存中的,而每一个线程运行时都有一个线程栈。当线程访问 i 的时候,首先找到堆内存的变量 i,然后把堆内存变量 i 的具体值load到线程本地内存中,建立一个变量副本,之后线程就不再和堆内存变量 i 有任何关系,而是直接修改副本变量的值。在修改完之后的某一个时刻(线程退出之前),自动把线程变量副本的值回写到堆中变量。这样在堆中 i 的值就产生变化了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值