请关注我的微信公众号
![](https://img.haomeiwen.com/i752311/0262bae944cdacc7.jpg)
个人微信公众号
技术交流群 (仅作技术交流):642646237
![](https://img.haomeiwen.com/i752311/8c3ec61411e9d39d.jpg)
请关注我的头条号:
![](https://img.haomeiwen.com/i752311/807e8ec13b68ff93.jpg)
诡异的内存——例子
![](https://img.haomeiwen.com/i752311/b9fa30d077400fef.png)
诡异的内存——例子——竞态条件
根据线程执行的时序,这段代码的输出可能是The meaning of life is XX或者I don't know the answer。
诡异的内存——例子——乱序执行
但是这个例子的运行结果也可能是:
The meaning of life is: 0
当answerReady
为true
时answer
值为0,也就是第6行和第7行颠倒了执行顺序。
诡异的内存——乱序执行
编译器的静态优化可以打乱代码的执行顺序;
JVM的动态优化也会打乱代码的执行顺序;
硬件可以通过乱序执行来优化其性能。
诡异的内存——内存不可见
![](https://img.haomeiwen.com/i752311/3e3dcbb62648113d.png)
answerReady
有可能不会变成true
导致代码无法退出。
诡异的内存——发生乱序和内存不可见的原因
编译器、JVM、硬件都不应插手修改原本的代码逻辑。
但是运行效率提升,尤其是共享内存架构的运行效率提升,都仰仗于此类代码优化。因此无法摆脱此类优化的副作用的影响。
内存可见性
Java内存模型定义了何时一个线程对内存的修改对另一个线程可见。基本原则是,如果读线程和写线程不进行同步,就不能保证可见性。
如何保证内存可见性
- 通过获取对象的内置锁;
- 开启一个线程并通过join()检查线程是否已经终止;
- 使用java.util.concurrent包提供的工具。
采用锁方式保证内存可见性注意事项
两个线程都需要进行同步。只有其中一个线程进行同步是不够的。
网友评论