二、Java内存模型(JMM)

82 阅读2分钟

Java内存模型(JMM)

JMM的概念

JMM其实是一种规范,用于解决多线程对于共享变量操作发生的并发问题

为什么会有JMM

因为不同的服务器硬件和操作系统是有差异的,JVM想要java程序在这些存在差异的环境中运行起来,制定了JMM这一套规范

JMM规范

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

image.png

JMM主内存和工作内存

主内存

  • 存储 Java 实例对象,包括成员变量、类信息、常量、静态变量等,但是不包括局部变量和方法参数
  • 主内存属于数据共享区域,多线程并发操作时会引发线程安全问题

工作内存

  • 存储当前方法的所有本地变量信息,每个线程只能访问自己的工作内存,每个线程工作内存的本地变量对其他线程不可见
  • 字节码行号指示器、Native 方法等信息
  • 属于线程私有数据区域,不存在线程安全问题

主内存和工作内存的数据存储类型和操作方式归纳

  • 对于实例对象中的成员方法,方法里的基本数据类型的局部变量将直接存储在工作内存的栈帧结构中。方法里引用类型的局部变量的引用在工作内存中的栈帧结构中,对象实例存储在堆中
  • 对于实例对象的成员变量,不管它是基本数据类型、包装类型还是引用类型,都会被存储到堆区
  • 对于实例对象中的静态变量以及类信息都会被存储在方法区中
  • 需要注意的是,在主内存中的实例对象可以被多个线程共享,如果两个线程调用了同一个对象的同一个方法,两个线程会将数据拷贝到自己的工作内存中,执行完成后刷新回主内存