6. Java 内存模型
6.1 并发模型
线程间进行通信和同步,可以通过 2 种方式的并发模型来实现:
- 消息传递并发模型
- 共享内存并发模型
Java 中,采用的是第二种:共享内存并发模型
6.2 JVM 运行时数据区
- 方法区 和 堆,是对所有线程内存共享的。
- 栈、PC 是线程私有的。
Java 中内存可见性是指堆中的共享变量。
6.3 Java 内存模型 JMM
JMM 即java 内存模型,它屏蔽了硬件与操作系统对内存访问的差异,从而实现了java程序的跨平台一致性。
JMM定义了线程和主内存之间的抽象关系:共享变量存储在主内存中,每个线程对应自己的私有工作内存。
- 线程对变量的所有操作都必须在工作内存中进行,不能直接读写主内存中的变量。
- 而线程之间通信也要以主内存为媒介,一个线程先把自己工作内存中的值刷新到主内存,然后另一个线程再从主内存中取值。
JMM主要解决了几个问题:
- 内存可见性问题。可以通过 volatile 或 synchronized 来实现。为什么存在内存可见性问题 -> volatile 解决内存可见性问题。
- 指令重排序问题。重排序的分类 -> happens before -> 内存屏障。
- 原子性问题。JMM 通过read,load,store等8个指令保证了对于基本类型变量、引用类型变量和volatile变量的读写是原子性的。但不包括i++这种复合操作,因为是先读值,再赋值。
- 如果想实现更大作用域的原子性,就要使用锁机制。
6.3.1 volatile 关键字
- 保证多线程操作共享变量的可见性
- 禁止指令重排序
具体看对 volatile
关键字的介绍。
6.3.2 JMM 与 运行时数据区 的关系
JMM 是抽象的概念。
- JMM 的主内存属于共享数据区域,包含堆、方法区;
- JMM 的本地内存属于私有数据区域,包含程序计数器、本地方法栈、虚拟机栈。