Java中的内存模型JMM
Java中的内存模型
包括三部分: 线程, 工作内存(本地内存),主内存
JMM定义了Java 虚拟机(JVM)在计算机内存(RAM)中的工作方式。
JMM是隶属于JVM的。从抽象的角度来看,JMM定义了线程和主内存之间的抽象关系:线程之间的共享变量存储在主内存(Main Memory)中,每个线程都有一个私有的本地内存(Local Memory)
1、主内存中存放着变量, 这里的变量是指一些实例数据, 静态变量及代码, 对于方法变量,局部变量为线程私有
2、工作内存:----中存储了该线程以读/写共享变量的副本。
工作内存是JMM的一个抽象概念,并不真实存在。它涵盖了缓存、写缓冲区、寄存器以及其他的硬件和编译器优化。
3、对于变量的读写操作必须在线程自己的工作内存中进行操作,而不同线程之间的通信,线程间变量值的传递均需要在主内存来完成。
工作内存和主内存之间的交互
主要有8步(也可简化成4步)
lock ---- 锁定,操作于主内存,声明此变量多线程情况下只允许一个线程访问,在对象头中添加锁信息
unlock ----操作于主内存, 释放锁资源
read ---- 操作于主内存中,将主内存的变量值读出
load ---- 装载,操作工作内存中,将主内存的变量装载出,以供工作内存使用
use ---- 使用,操作于工作内存中,将变量的值交给执行引擎
assign ----赋值,操作于工作内存中,由执行引擎将 值 赋 给变量
store ---- 存储,操作于工作内存中,将把工作内存中一个变量的值传送到主内存
write ---- 操作于主内存,将值写入 主内存
简化的四步
read load store write
JMM的三个特性
1、原子性(Atomic)
是指: 对共享内存的操作必须是要么全部执行直到执行结束,且中间过程不能被任何外部因素打断,要么就不执行。被称为原子性。
2、可见性()
是指: 多线程在自己的工作内存操作共享内存的副本时,执行结果后能够及时的同步到共享内存,确保其他线程对此结果及时可见。
3、有序性()
我们首先要知道程序的执行顺序按照代码顺序执行,在单线程环境下,程序的执行都是有序的,
但是在多线程环境下,JMM 为了性能优化,编译器和处理器会对指令进行重排-----乱序执行优化,程序的执行会变成无序。
指令重排的意义:可以保证串行语义一致,但是没有义务保证多线程间的语义一致,对于提高CPU处理性能是十分重要的
但是在 JVM内部有些指令是不能重排的,了解一下 Happens-Before原则(先行发生原则)
-
程序顺序原则:一个线程内保证语义的串行性
-
volatile规则:volatile 变量的写,先发生于读,这保证了volatile变量的可见性
-
锁规则:解锁(unlock)必然发生在随后的加锁(lock)前
-
传递性:A先于B,B先于C,那么A必然先于C
-
线程的start()方法先于它的每一个动作
-
线程的所有操作先于线程的终结(Thread.join())
-
线程的中断(interrupt())先于被中断线程的代码
-
对象的构造函数执行,结束先于finalize() 方法
结语
JMM的三大特性,有效的保证了多线程之间的通信规则,防止了脏数据的出现,对于去保证线程安全提供了思路。
关于volatile及synchronized 语义,及如何从jmm的三大特性来保证线程安全下一章节会讲。
[本文链接]:https://editor.csdn.net/md?articleId=106492089