java内存模型的主要目标是定义程序中各个变量的访问规则,即在虚拟机中将变量存储到内存和从内存中取出变量这样的底层细节。
注意:此处的不变量包括实例字段,静态字段和构成数组对象的元素,但是不包括局部变量与方法参数,因为这些都是线程是有的,不会被共享,自然就不存在竞争的问题。
java内存模型规定所有的变量都存储在主内存。每条线程还有自己的工作内存,线程的工作内存保存了该线程使用到的变量的主内存副本拷贝,线程对变量的所有操作(读取,赋值等)都必须在工作内存中进行,而不能直接读写主内存中的变量。
内存间交互操作
java内存模型定义了8中操作来完成。
lock(锁定):用于主内存 的变量,它把一个变量标识为一条线程独占的状态。
unlock(解锁); 作用于主内存的变量,把一个处于锁状态的变量释放处理
read(读取):作用于主内存的变量,把一个变量的值从主内存传输到线程的工作内存中,以便随后的load动作使用。
load(载入):作用于工作内存的变量,把read操作内存中得到的变量值放入工作内存的变量副本中。
use(使用):作用于工作内存的变量,报工作内存中一个变量的值传递给执行引擎,每当虚拟机遇到一个需要使用到变量的值节码指令时执行这个操作。
assign(赋值):作用于工作内存的变量,把一个从执行引擎接收到的值赋值给工作内存的变量,每当虚拟机遇到一个给变量赋值的字节码指令时执行这个操作
sotre(存储):作用于工作内存的变量,报工作内存中的一个变量的值传送到主内存中,以便随后的write操作使用。
wirte(写入):作用于主内存的变量,把store操作从工作内存中得到的变量值放入主内存的变量中。
volatile的使用
1、volatile可以保证变量的线程可见性
2、禁止指令重排序优化。
普通的变量仅仅保证在该方法的执行过程中所有依赖赋值的结果的地方都能获取到正确的结果,而不能保证变量赋值操作的顺序与程序代码中的执行顺序一致。因为在一个线程的方法执行过程中无法感知到这点,这也就是java内存模型中描述的所谓的“线程内表现串行的语义”。