天天看点

java并发之内存模型(JMM)

一、java内存模型(JMM)是什么

  • JMM是一种抽象的概念,它描述了一系列的规则或者规范,用来解决多线程的共享变量问题,比如volatile,synchronized等就是围绕JMM的语法。这里所说的变量,包括实例字段,静态字段,但不包括局部变量和方法参数,因为后者是线程私有的,不存在竞争问题。
  • JVM试图定义一种统一的内存模型,将各种底层硬件以及操作系统的内存访问差异进行封装,使java程序在不同硬件以及操作系统上都能达到相同的并发效果。它分为工作内存和主内存,线程无法对主内存直接进行操作,如果一个线程要和另一个线程通信,那么只能借助主内存进行共享。

二、主内存与工作内存
java并发之内存模型(JMM)

  • 由于JVM运行程序的实体是线程,每个线程创建时JVM都会为其创建一个工作内存,工作内存是每个线程的私有数据区域。而JMM规定所有变量都存储在主内存,主内存是共享内存区域,所有线程都可以访问,但线程对变量的操作(读取赋值等)必须在工作内存中进行,首先要将变量从主内存拷贝到自己的工作内存空间,然后对变量进行操作,操作完成后再将变量写回主内存,不能直接操作主内存中的变量,各个线程中的工作内存中存储着主内存的变量副本拷贝,线程之间无法访问对方的工作内存,线程间的通信必须通过主内存完成。
  • 每个线程只能够直接接触到工作内存,无法直接操作主内存,而工作内存中所保存的正是主内存的共享变量的副本,主内存和工作内存之间的通信是由 JMM 控制的。
  • 那这些内存区域都是在哪存储的呢?如果非要有个对应的话,你可以认为主内存中的内容对应java堆的对象,而工作内存对应的则是虚拟机栈中的内容。但实际上,主内存也可能存在于高速缓存,或者CPU的寄存器上;工作内存也可能存在于硬件内存中,我们不用太纠结具体的存储位置。

三、JMM 规定

  1. 所有的变量都存储在主内存中,同时每个线程拥有自己独立的工作内存,而工作内存中的变量的内容是主内存中该变量的拷贝。
  2. 线程不能直接读 / 写主内存中的变量,但可以操作自己工作内存中的变量,然后再同步到主内存中,这样,其他线程就可以看到本次修改。
  3. 主内存是由多个线程所共享的,但线程间不共享各自的工作内存,如果线程间需要通信,则必须借助主内存中转来完成。

四、三个特性

  • 可见性
  • 原子性
  • 有序性