JMM是一种规范,规定了一个线程如何和什么时候能够看到由其余线程修改事后的共享变量的值以及在必须时如何同步地访问共享变量。架构
Heap(堆):运行时的数据区,由垃圾回收负责,优点是能够动态分配内存大小,生存期没必要事先告诉编译器,垃圾收集器会自动回收再也不使用的数据。缺点是因为要在运行时动态分配内存因此存取速度相对较慢。线程
Stack(栈):优点是存取速度比堆快,仅次于计算机里的寄存器,数据可共享。缺点是数据大小与生存期必须是肯定的缺乏灵活性,所以栈中主要存放一些基本类型的变量。cdn
调用栈和本地变量存放在栈上,对象存放在堆上,如上图本地变量对对象的引用也是存放在线程栈上的。一个对象的成员变量可能会随着对象自身存放在堆上,静态成员变量跟随类的定义一块儿存放在堆上,存放在堆上的对象能够被持有这个对象引用的线程访问,当一个线程能够访问一个对象的时候也能够访问这个对象的成员变量。对象
**注意:**若是两个线程同时调用同一个对象上的同一个方法,它们都访问这个对象的成员变量可是每一个线程都拥有了这个成员变量的私有拷贝。blog
规则:内存
1.不容许Read,Load,Write,Store操做单一出现,必须按顺序执行,但能够不连续执行,即Read和Load之间,Store和Write之间是能够插入其余指令的。编译器
2.不容许一个线程丢弃最近的Assign操做,也就是说变量工做内存中改变以后必须将变化同步给主内存。同步
3.一个新的变量只能在主内存中诞生,不容许在工做内存中直接使用一个未被初始化的变量。it
4.一个变量在同一时刻只容许一个线程对其执行Lock操做,可是Lock操做能够被同一条线程执行屡次,这样之后只有执行相同次数的Unlock变量才会被解锁。io
5.若一个变量执行了Lock操做,将会清空工做内存中此变量的值。在执行引擎使用这个变量以前须要从新Load
6.一个变量没有被Lock时不容许对其执行Unlock,也不容许Unlock一个其余线程锁定的变量。对一个变量Unlock以前必须先把此变量同步回主内存。
Written by Autu.
2019.7.5