线程,工作内存与主内存

Java 不同现场的工作内存无法直接相互访问,线程间的变量的传递需要通过主内存进行。

Jvm 定义了下面 8 中内存操作:

  • lock(锁定):作用于主内存的变量,它把一个变量标识为一条线程独占的状态
  • unlock(解锁):作用于主内存的变量,它把一个处于锁定状态的变量释放出来,释放后的变量才可以被其他线程锁定。
  • read(读取):作用于主内存的变量,它把一个变量的值从主内存传输到线程的工作内存中,以便随后的load动作使用
  • load(载入):作用于工作内存的变量,它把read操作从主内存中得到的变量值放入工作内存的变量副本中
  • use(使用):作用于工作内存的变量,它把工作内存中一个变量的值传递给执行引擎,每当虚拟机遇到一个需要使用变量的值的字节码指令时将会执行这个操作
  • assign(赋值):作用于工作内存的变量,它把一个从执行引擎接收的值赋给工作内存的变量,每当虚拟机遇到一个给变量赋值的字节码指令时执行这个操作
  • store(存储):作用于工作内存的变量,它把工作内存中一个变量的值传送到主内存中,以便随后的 write 操作使用
  • write(写入):作用于主内存的变量,它把store操作从工作内存中得到的变量的值放入主内存的变量中

(read, load 和 store, write 不能单独使用,类似于汇编中的内存加载,原因在于内存的操作并不是通过 DMA 进行的,需要将操作的值保存到一个中间寄存器中)

volatile 的两项特性

  1. 对 volatile 变量的修改完成立刻对所有线程可见
    (volatile 变量的值每次都通过 read,load 从主内存中获得,同样的,对 vlolatile 的赋值也立刻通过 store, write 更新到主内存中,当然不会直接使用这种方法,JVM 根据 use, assign 等的顺序保证)
  2. 禁止指令重排序优化

volatile 保证内存并发模型中的可见性和有序性,而不保证原子性。