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