内存模型 JMM


6. Java 内存模型

6.1 并发模型

线程间进行通信和同步,可以通过 2 种方式的并发模型来实现:

  1. 消息传递并发模型
  2. 共享内存并发模型

Java 中,采用的是第二种:共享内存并发模型

6.2 JVM 运行时数据区

java运行时数据区

  • 方法区 和 堆,是对所有线程内存共享的。
  • 栈、PC 是线程私有的。

Java 中内存可见性是指堆中的共享变量。

6.3 Java 内存模型 JMM

JMM 即java 内存模型,它屏蔽了硬件与操作系统对内存访问的差异,从而实现了java程序的跨平台一致性。

JMM定义了线程主内存之间的抽象关系:共享变量存储在主内存中,每个线程对应自己的私有工作内存

  • 线程对变量的所有操作都必须在工作内存中进行,不能直接读写主内存中的变量。
  • 而线程之间通信也要以主内存为媒介,一个线程先把自己工作内存中的值刷新到主内存,然后另一个线程再从主内存中取值。

JMM主要解决了几个问题:

  1. 内存可见性问题。可以通过 volatile 或 synchronized 来实现。为什么存在内存可见性问题 -> volatile 解决内存可见性问题。
  2. 指令重排序问题。重排序的分类 -> happens before -> 内存屏障。
  3. 原子性问题。JMM 通过read,load,store等8个指令保证了对于基本类型变量、引用类型变量和volatile变量的读写是原子性的。但不包括i++这种复合操作,因为是先读值,再赋值。
    • 如果想实现更大作用域的原子性,就要使用锁机制。

JMM内存模型

6.3.1 volatile 关键字

  • 保证多线程操作共享变量的可见性
  • 禁止指令重排序

具体看对 volatile 关键字的介绍。

6.3.2 JMM 与 运行时数据区 的关系

JMM 是抽象的概念。

  • JMM 的主内存属于共享数据区域,包含堆、方法区;
  • JMM 的本地内存属于私有数据区域,包含程序计数器、本地方法栈、虚拟机栈。

文章作者: Yu Yang
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Yu Yang !
 上一篇
3.线程状态及其转化 3.线程状态及其转化
3. 线程状态及其转化线程是轻量级进程,所以线程和进程状态一致。 Java 线程状态转化图: 3.1 Java 线程的 6 个状态Thread.State 源码: public enum State { NEW,
下一篇 
7.指令重排 与 happens-before 7.指令重排 与 happens-before
7. 指令重排 与 happens-before指令重排可以在 CPU 闲置(等待变量装载等)时,先执行其他指令,提高性能。分为: 编译器优化重排:编译器在不改变单线程程序语义的前提下,可以重新安排语句的执行顺序。 指令并行重排:现代处理
  目录