Java虚拟机规范中试图定义一种Java内存模型来屏蔽掉各种硬件和内存访问的差异,以实现让Java程序在各种平台下都能达到一致的内存访问效果,注意这里的模型指的是概念模型。
主存内与工作内存
主内存:JVM中存储变量(局部变量和方法参数除外)的内存区域
工作内存:线程私有的内存,保存了被该线程使用到的变量的主内存副本拷贝
Java内存模型定义了8种操作,它们是原子的:
- lock:给变量上锁
- unlock:给变量解锁
- read:从主内存中读取变量到工作内存
- load:将read到的值赋值到工作内存的变量中
- use:把工作内存中的一个变量值传递给执行引擎
- assign:把从执行引擎收到的值赋值给工作内存中的变量,赋值操作(=)会用到它
- store:把工作内存的中的变量转送到主内存中
- write:把store的变量值放入主内存
Java内存模型还规定了执行上述操作必须满足的规则,它和volatile关键字共同作用以保证内存访问操作在并发环境下的安全性。
volatile关键字的作用:
1. 保证变量的可见性,即每次读取变量都要从主内存获取值,每次赋值变量都要将工作内存中的变量同步会主内存
2. 禁止指令重排,保证了有序性
synchronized关键字字节码变异成moniterenter和moniterexit,而这两个字节码指令就使用了lock和unlock指令,来保证操作的原子性和有序性
先行发生原则:线程中一个操作发生在另一个线程的另一个操作之前,java有许多内置先行发生原则,其实就是使用后会保证不同线程操作先后顺序的方法