目录

因为存在重排序的过程所以我们要解决2个问题

  1. 编译,运行时重排序对编程的影响
  2. 内存可见性

编译,运行时重排序对编程的影响

重排序规则

as-if-serial语义

对于单线程来说,cpu可以保证程序执行的结果(可能经过重排序)和顺序执行代码的结果一致。编译器、和处理器进行重排序时都满足as-if-serial语义

在单线程中满足as-if-serial语义,那在多线程中就不同了!!!!!!

内存可见性

单线程,单cpu

多线程,单cpu

假如cpu按如下顺序执行指令

  1. 线程1开始,执行:obj.ready=true
    1. obj.ready=true;obj.data=1之间没有数据依赖关系,可以被重排序,可能按任意顺序执行
  2. 线程1暂停,线程2被调度,执行:if (obj.ready)
  3. 线程2被调度,执行:doSome(obj.data)问题来了,线程1还没有初始化obj.data呢,就被线程2使用了

要解决这个问题,必须要有一种策略保证obj.ready=true 比 obj.data=1先执行这个机制就是内存屏障

内存屏障

java中很多关键字的特性就是通过封装内存屏障实现的

更多参考:http://ifeve.com/linux-memory-barriers/#memory-barriers

多线程,多cpu

引起内存可见性的原因,cpu、线程都有自己的缓存区,更新的变量没有及时刷新到共享内存,导致其他线程不可见

如下图,要保证程序正常执行:

  1. 线程1的2行代码,必须按顺序调度到cpu1中执行
  2. cpu将执行结果按顺序写回到线程1的私有内存区
  3. 线程1将新值,按顺序写会共享内存
  4. 线程2从主内存按顺序读取最新的值
  5. 将最新值按顺序被cpu2处理

看看需要哪些技术可以保证以上5各步骤正常运行

参考:http://blog.csdn.net/dlutbrucezhang/article/details/10170649