java – x86上如何使用volatile发生丢失的更新?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java – x86上如何使用volatile发生丢失的更新?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含1234字,纯文字阅读大概需要2分钟。
内容图文
![java – x86上如何使用volatile发生丢失的更新?](/upload/InfoBanner/zyjiaocheng/752/ab328ed65ec241ffa13a4aac0e69d286.jpg)
我尝试使用’count’作为volatile运行以下代码:
ExecutorService e = Executors.newFixedThreadPool(2);
for (int i=0; i<2; i++)
{
e.execute(new Runnable(){
public void run() {
for (int i=0; i<1000000; i++)
count++;
}
}
);
}
e.shutdown();
e.awaitTermination(1, TimeUnit.DAYS);
System.out.println(count);
计数通常最终不到1,000,000.
我正在使用x86处理器 – 英特尔酷睿2双核E8400,热点1.6.24.
对于与volatile变量一起使用的运算符,通常会丢失更新参数,目的是实现原子更新,如下所示:
线程1和1都是2读取值0表示v,两者都将其递增1并写入值1.
在x86上使用volatile时,这个论点似乎分崩离析,因为:
1)每次访问volatile变量都会通过CPU缓存层次结构.只有当JVM能够证明单个线程访问volatile变量时,JVM才能生成汇编代码以多次访问volatile,而不会从内存中加载/存储,这不是这里的情况.
2)只有一个CPU可以在修改状态下拥有特定的高速缓存行,因此如果两个CPU都尝试增加v,则只有一个CPU会成功将包含v的高速缓存行转换为修改状态.另一个将使其高速缓存行无效,并且稍后将进入修改状态,其高速缓存包含正确的值1并将该变量更新为2.
我在这里错过了什么?
解决方法:
你错过了不是原子操作的事实.
如果您将代码重写为:
for (int i=0; i<1000000; i++)
int tmp = count;
tmp = tmp + 1;
count = tmp;
}
这会让它更清楚吗?这里不需要内存模型或缓存行详细信息 – 我们需要的是两个线程,它们都读取相同的值,都进行独立工作,然后再次存储它们的计算值.
内容总结
以上是互联网集市为您收集整理的java – x86上如何使用volatile发生丢失的更新?全部内容,希望文章能够帮你解决java – x86上如何使用volatile发生丢失的更新?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。