JMM是一种抽象的概念,旨在定义程序中变量的访问规则,以及在并发的情况下如何和何时可以看到其他线程引起的变化,JMM是为了帮助开发者了解多线程程序的内存可见性,原子性,有序性问题
组成
1. 主内存与工作内存
- 主内存(Main Memory):所有的变量都存储在主内存中,对所有线程来说是共享的。
- 工作内存(Working Memory):每个线程都有自己的工作内存,其中包含了该线程用到的变量的主内存副本。
这种设计允许线程执行操作时,可以在自己的工作内存中快速读写,而不是直接在主内存中进行,提高了执行效率。但这也引入了内存可见性问题,因为一个线程对某个变量的修改,不一定立即对其他线程可见。
2. 内存交互操作
JMM定义了8种操作,用来完成线程之间的交互,确保内存的一致性和线程的协调工作,这些操作包括:
lock
(锁定)/unlock
(解锁)read
(读取)/load
(载入)use
(使用)/assign
(赋值)store
(存储)/write
(写入)
这些操作必须按照特定的规则执行,以保证不同线程间的内存可见性、原子性和有序性。
3. happens-before
原则
happens-before
原则是JMM的基石,它定义了一个全局的顺序规则,这个规则决定了一个操作的结果对另一个操作可见的条件。如果一个操作A happens-before
另一个操作B,那么JMM保证A操作的结果对B操作是可见的。这个原则提供了一种判断数据是否安全发布和线程间通信是否正确的方式。
4. 同步原语
JMM通过一系列的同步原语(如synchronized
、volatile
、final
和并发包中的工具)来实现内存的可见性、原子性和有序性。这些原语让开发者有能力编写出正确的多线程程序:
synchronized
:可以确保同时只有一个线程可以执行同步代码段,并且在访问共享变量时提供内存可见性和互斥访问。volatile
:保证了变量的修改对所有线程立即可见,并禁止指令重排序。final
:用于声明常量,保证实例一旦构建完成,其他线程就能正确地看到由final
字段构成的状态。