一、内存模型
java内存模型
Java内存模型描述了在多线程代码中,哪些行为是正确的、合法的,以及多线程之间如何进行通信,代码中变量的读写行为如何反应到内存、CPU缓存的底层细节。
处理器和内存的交互
这个要感谢硅工业的发展,导致目前处理器的性能越来越强大。目前市场上基本上都是多核处理器。如何利用多核处理器执行程序的优势,使得程序性能得到极大的提升,是目前来说最重要的。
目前所有的运算都是处理器来执行的,我们在大学的时候就学习过一个基本概念 程序 = 数据 + 算法 ,那么处理器负责计算,数据从哪里获取了?
数据可以存放在处理器寄存器里面(目前x86处理都是基于寄存器架构的),处理器缓存里面,内存,磁盘,光驱等。处理器访问这些数据的速度从快到慢依次为:寄存器,处理器缓存,内存,磁盘,光驱。为了加快程序运行速度,数据离处理器越近越好。但是寄存器,处理器缓存都是处理器私有数据,只有内存,磁盘,光驱才是才是所有处理器都可以访问的全局数据(磁盘和光驱我们这里不讨论,只讨论内存)如果程序是多线程的,那么不同的线程可能分配到不同的处理器来执行,这些处理器需要把数据从主内存加载到处理器缓存和寄存器里面才可以执行(这个大学操作系统概念里面有介绍),数据执行完成之后,在把执行结果同步到主内存。如果这些数据是所有线程共享的,那么就会发生同步问题。处理器需要解决何时同步主内存数据,以及处理执行结果何时同步到主内存,因为同一个处理器可能会先把数据放在处理器缓存里面,以便程序后续继续对数据进行操作。所以对于内存数据,由于多处理器的情况,会变的很复杂。
定义
内存模型就是规定了一个规则,处理器如何同主内存同步数据的一个规则。
创建对象步骤
1、分配内存空间
2、创建空的对象
3、初始化空的对象
4、把初始化完成的对象引用指向变量
内存屏障(Memory Barrier)
在不同CPU执行的不同线程对同一个变量的缓存值不同。
读屏障 load barrier
在指令前插入load barrier,可以让高速缓存中的数据失效,强制重新从主内存中加载数据。
写屏障 store barrier
在指令后插入store barrier,能让写入缓存中的最新数据更新写入主内存,让其它线程可见。
volatile
volatile底层是怎么实现保证不同线程可见性的,这里涉及到的就是硬件上的,被volatile修饰的变量在进行写操作时,会生成一个特殊的汇编指令,该指令会触发mesi协议,会存在一个总线嗅探机制的东西,简单来说就是这个cpu会不停检测总线中该变量的变化,如果该变量一旦变化了,由于这个嗅探机制,其它cpu会立马将该变量的cpu缓存数据清空掉,重新的去从主内存拿到这个数据