转载文章
简述
Java虚拟机规范中试图定义一种Java内存模型(Java Memory Model,JMM)来屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的内存访问效果。
作用
Java内存模型的主要目标是定义程序中各个变量的访问规则,即在虚拟机中将变量存储到内存和从内存中取出变量这样的底层细节。
这里说的变量包括实例字段、静态字段和构成数组对象的元素,不包括局部变量与方法参数,因为后者是线程私有的,不会共享,也就不存在竞争的问题。
主内存与工作内存
Java内存模型规定了所有的变量都存储在主内存(Main Memory)中,此外每条线程还有自己的工作内存(Working Memory)。
线程的工作内存中保存了被该线程使用到的变量的主内存副本拷贝,线程对变量的所有操作(读取、赋值等)都必须在工作内存中进行,不能直接读写主内存中的变量。
并且,不同的线程之间也无法直接访问对方工作内存中的变量,线程间变量值得传递均需要通过主内存来完成,线程、主内存、工作内存关系如下图:
内存间的交互动作
内存动作 | 作用 |
---|---|
lock(锁定) | 作用于主内存变量,把一个变量标示为一条线程独占的状态 |
unlock(解锁) | 作用于主内存的变量,把一个处于锁定状态的变量释放出来,释放后的变量才可以被其他线程锁定read(读取) |
read(读取) | 作用于主内存的变量,把一个变量的值从主内存传输到线程的工作内存中,以便随后的load动作使用 |
load(载入) | 作用于工作内存的变量,把read操作从主存中得到的变量值放入工作内存的变量副本中 |
use(使用) | 作用于工作内存的变量,把工作内存中一个变量的值传递给执行引擎,每当虚拟机遇到一个需要使用到变量的值的字节码指令时将会执行这个操作 |
assign(赋值) | 作用于工作内存的变量,把一个从执行引擎接收到的值赋给工作内存中的变量,每当虚拟机遇到一个给变量赋值的字节码指令时执行这个操作 |
store(存储) | 作用于工作内存的变量,把工作内存中一个变量的值传送到主内存中,以便随后的write操作使用 |
write(写入) | 作用于主内存的变量,把store操作从工作内存中得到的变量的值放入主内存的变量中 |
常见问题:
Java中的volatile 变量是什么
可见性,是指线程之间的可见性,一个线程修改的状态对另一个线程是可见的。volatile关键字可以保证直接从主存中读取一个变量,如果这个变量被修改后,总是会被写回到主存中去。当对非 volatile 变量进行读写的时候,每个线程先从主内存拷贝变量到工作内存(CPU缓存)中,多个线程多个变量副本,操作后数值可能会不一样的。