> 文章列表 > 【JVM】JMM

【JVM】JMM

【JVM】JMM

一、Java内存模型

  • Java内存模型Java Memory Model,JMM是一个抽象概念,定义了程序中各种变量访问规范,即关注在虚拟机中把变量存储到内存和从内存中取出变量值这样的底层细节。
  • 在虚拟机中的运算单元就是线程,因此可以理解为JMM定义的就是线程访问共享变量的方式。

1. 缓存一致性

  • CPU读写速率高,需要通过 高速缓存 实现和主存(物理内存)交互。
  • 多核心CPU,每个处理器都有自己的高速缓存,而它们又共享同一个主内存,可能导致各自缓存数据不一致的问题。
  • 为了解决缓存一致性问题,制定了缓存一致性协议。

2. Java内存模型(JMM)

  • JMM规定所有变量都存储在主内存中,每条线程还有自己的工作内存。
  • 线程的工作内存中保存了被线程使用的变量的主内存副本,线程对变量的所有操作都必须在工作内存中进行,而不能直接读写主内存中的数据。
  • 不同线程之间也无法直接访问对方的工作内存中的变量,线程间变量值的传递需要通过主内存来完成。 也就是说Java线程之间的通信采用的是共享内存。
    在这里插入图片描述
  • Java内存模型与Java内存区域并不是同一个层次对内存的划分,可以说两者并没有什么关系。
    JMM与Java内存区域唯一相似点,都存在共享数据区域和私有数据区域。
    在JMM中主内存属于共享数据区域,对应堆和方法区。工作内存数据线程私有数据区域,对应程序计数器、虚拟机栈以及本地方法栈。

3. happens-before原则(先行发生原则):

JMM供了happens-before 原则来辅助保证程序执行的原子性、可见性以及有序性的问题,它是判断数据是否存在竞争、线程是否安全的依据:

  • 程序次序规则:一个线程内,按照代码顺序,书写在前面的操作先行发生于书写在后面的操作
  • 锁定规则:一个unLock操作先行发生于后面对同一个锁额lock操作
  • volatile变量规则:对一个变量的写操作先行发生于后面对这个变量的读操作
  • 传递规则:如果操作A先行发生于操作B,而操作B又先行发生于操作C,则可以得出操作A先行发生于操作C
  • 线程启动规则:Thread对象的start()方法先行发生于此线程的每个一个动作
  • 线程中断规则:对线程interrupt()方法的调用先行发生于被中断线程的代码检测到中断事件的发生
  • 线程终结规则:线程中所有的操作都先行发生于线程的终止检测,我们可以通过Thread.join()方法结束、Thread.isAlive()的返回值手段检测到线程已经终止执行
  • 对象终结规则:一个对象的初始化完成先行发生于他的finalize()方法的开始

二、