说到底JMM其实是定义了线程和主存之间的关系。每个线程都有一个本地内存,存储了主存中共享变量、资源的副本。JMM控制了多个线程之间的通讯。通讯同步的约定:
- 线程解锁前,必须把共享变量立刻刷回主存。
- 线程加锁前,必须读取主存中的最新值到工作内存中!
- 加锁和解锁是同一把锁
JMM作为一个语言级的内存模型,在不同的编译器和处理器上,通过禁止特定类型的编译器和处理器重排序,提供一致的内存可见性保证。
- 对于编译器重排序:JMM会禁止特定类型的编译器重排序
- 对于处理器重排序:JMM会要求JVM在生成指令序列的时候,插入特定类型的内存屏障(Memory Barriers)来禁止处理器重排序
as-if-serial语义:
不管编译器和处理器为了提供并行度做怎样的重排序,单线程程序的执行结果不能被改变。
Happens-before:
如果一个操作happens-before另一个操作,那么第一个操作的执行结果对第二个操作可见,但是第一个操作的执行顺序不一定排在第二个之前