概述
听说当两条指令互相不依赖的时候,在cpu或者jvm那儿可能会为了提高性能而进行指令重排。
数据依赖
比如下面两条代码就没有数据依赖:
int a = 5;
int b= 2;
这两条指令先后顺序并不影响程序运行逻辑,重排也是是没有问题的。
多线程
但是,听说在多线程的时候就会出现问题,因为单个线程有依赖可以检测出来。
多个线程操作同一个对象的时候,因为每个线程都有自己的工作区,主存与工作内存交互不及时,就会导致数据出问题。
来个例子:
代码分析:
/** * 理论上来说: * 1.线程1先执行完,线程2开始执行 * a=1; * flag=true; * if (flag) { * a = a + 5; * System.out.println("reValue:" + a); * } * 运行结果是:输出reValue:6 * * 2.线程1先执行一半,线程2执行 * a=1; * if (flag) { * a = a + 5; * System.out.println("reValue:" + a); * } * flag=true; * 运行结果:无。 * * 3.线程2先执行,线程1开始执行 * if (flag) { * a = a + 5; * System.out.println("reValue:" + a); * } * a=1; * flag=true; * 运行结果是:无。 * * 如果在线程1中发生指令重排!!!!! * 就会出现: * 线程1先执行一半,线程2执行 * flag=true; * if (flag) { * a = a + 5; * System.out.println("reValue:" + a); * } * a=1; * 运行结果:控制台输出reValue:a */
点击查看
运行结果:
实不相瞒,秉持着实事求是的原则,不经历过的我不信。
我i5第十二代处理器,运行了一晚上,只出了这一次指令重排。它真的,我哭死。
还好运行出来一次,我勉强信了。
总结
它如何产生:
就是因为每个线程都有自己的工作内存,而工作内存与主内存交互不够及时呗。
它如何解决:
当你觉得某个变量会因为指令重排而导致线程不安全,那么对其使用volatile的声明,它使得变量及时地在主存中更新 :
1、对volatile变量的写会立即刷新到主存
2、对volatile变量的读会读主存中的新值
原文地址:http://www.cnblogs.com/lurenjia-bky/p/16886709.html
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,请务用于商业用途!
3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员!
8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载
声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性