java内存模型

来源:互联网 发布:人工智能图像识别原理 编辑:程序博客网 时间:2024/05/03 16:03

一、概述

java虚拟机规范中试图定义一种java内存模型(Java Memory Model,JMM)来屏蔽掉各种硬件和操作系统的内存访问差异,以实现让java程序在各种平台下都能达到一致的并发效果。在此之前,主流程序语言(C/C++等)直接使用物理硬件(操作系统的内存模型),但会因为平台的不同而发生并发访问错误。
JDK1.5(实现了JSR-133)发布后,java的内存模型已经成熟和完善起来了。

二、主内存和工作内存

  1. Java内存模型的主要目标是定义程序中各个变量的访问规则,即在虚拟机中将变量存储都内存和从内存中取出变量这样的底层细节。此处的变量包括实例字段、静态字段和构成数组对象的元素,但是不包括局部变量和方法参数,因为后者是线程私有的,不存在竞争问题。
  2. Java内存模型规定了所有变量都存储在主内存(虚拟机内存的一部分)中。每条线程还有自己的工作内存(类比高速缓存),线程的工作内存中保存了被该线程使用到的变量的主内存副本拷贝,线程对变量的所有操作都必须在工作内存中进行,而不能直接读写主内存中的变量。不同的线程之间也无法直接访问对方工作内存中的变量,线程间变量值得传递均需要通过主内存来完成,线程、主内存、工作内存三者的交互关系如下:

三、内存间的交互操作

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

四、volatile

  1. java虚拟机提供的最轻量级的同步机制。
  2. 当一个变量被定义成volatile后,它将具备两种特性。第一是保证此变量对所有线程的可见性(指当一条线程修改了这个变量的值,新值对于其他线程来说可以立即得知的),但该变量在各个线程的工作内存不存在一致性问题,从字节指令来看,栈顶变量会过期。第二是禁止指令重排序优化

五、long、double型变量的特殊规则

  1. 允许虚拟机将没有被volatile修饰的64位数据的读写操作划分为两次32位的操作来进行,即所谓的非原子性的协定。

六、原子性、可见性与有序性

  1. 原子性:提供了原子性操作,即使是long和double数据,在处理上也大多作为原子操作对待。
  2. 可见性:指当一个线程修改了共享变量的值,其他线程能够立即得知这个修改。volatile、synchronized和final都能实现可见性。
  3. 有序性:如果在本线程内观察,所有的操作都是有序的;如果在一个线程中观察另一个线程,所有操作都是无序的。

七、先行发生原则

  1. 程序次序规则。
  2. 管程锁定规则。
  3. volatile变量规则。
  4. 线程启动规则。
  5. 线程终止规则。
  6. 线程中断规则。
  7. 对象终结规则。
  8. 传递性。
原创粉丝点击