共计 1316 个字符,预计需要花费 4 分钟才能阅读完成。
什么是 JMM?
JMM 就是 Java 内存模型 (java memory model)。因为在不同的硬件生产商和不同的操作系统下,内存的拜访有肯定的差别,所以会造成雷同的代码运行在不同的零碎上会呈现各种问题。所以 java 内存模型(JMM) 屏蔽掉各种硬件和操作系统的内存拜访差别,以实现让 java 程序在各种平台下都能达到统一的并发成果。
在计算机硬件层面,CPU 在解决指令时,会先从 L1,L2,L3 缓存中拉取数据,如果没有再从主内存中获取,JMM 就是再 CPU 缓存和主内存之间协调,定义了 Java 线程根本的工作形式,保障了原子性,可见性,有序性的。
Java 内存模型规定所有的变量都存储在主内存中,包含实例变量,动态变量,然而不包含局部变量和办法参数。每个线程都有本人的工作内存,线程的工作内存保留了该线程用到的变量和主内存的正本拷贝,线程对变量的操作都在工作内存中进行,而后再刷回主内存,线程不能间接读写主内存中的变量。
JMM8 种内存交互方式
lock(锁定):作用于主内存的变量,它把一个变量标识为一条线程独占的状态。
unlock(解锁):作用于主内存的变量,它把一个处于锁定状态的变量释放出来,开释后的变量才能够被其余线程锁定。
read(读取):作用于主内存的变量,它把一个变量的值从主内存传输到线程的工作内存中,以便随后的 load 动作应用。
load(载入):作用于工作内存的变量,它把 read 操作从主内存中失去的变量值放入工作内存的变量正本中。
use(应用):作用于工作内存的变量,它把工作内存中一个变量的值传递给执行引擎,每当虚拟机遇到一个须要应用到变量的值的字节码指令时将会执行这个操作。
assign(赋值):作用于工作内存的变量,它把一个从执行引擎接管到的值赋给工作内存的变量,每当虚拟机遇到一个给变量赋值的字节码指令时执行这个操作。
store(存储):作用于工作内存的变量,它把工作内存中一个变量的值传送到主内存中,以便随后的 write 操作应用。
write(写入):作用于主内存的变量,它把 store 操作从工作内存中失去的变量的值放入主内存的变量中。
JMM 特色
原子性
JMM 只能保障根本的原子性,如果要保障一个代码块的原子性,提供了 monitorenter 和 moniterexit 两个字节码指令,也就是 synchronized 关键字。因而在 synchronized 块之间的操作都是原子性的。
可见性
可见性是指变量的变动及在线程之间是可见的
volatile:当变量被 volatile 润饰时,这个变量被批改后会立刻刷新到主内存中,当线程读取这个变量时,也会间接从主内存中读取(当 volatile 润饰的是援用数据类型,只能保障援用的内存地址是可见,不保障对象的外部属性可见)
synchronized: 在执行完同步代码后,unlock 之前必须把共享变量刷新到主内存中。
final:常量,线程无奈更改。
有序性
volatile: 应用内存屏障达到禁止指令重排序,以保障线程操作的有序性。
synchronized:一个线程 lock 之后,必须 unlock 后,其余线程才能够从新 lock,使得被 synchronized 包住的代码块在多线程之间的操作是串行执行的。