Java 内存模型(JMM)是一种抽象的概念,并不真实存在,它描述了一组规则或规范,围绕原子性、有序性和可见性展开,通过这组规范定义了程序中各个变量(包括实例字段、静态字段和构成数组对象的元素)的访问方式。
线程中共享变量都存储在主内存中,每个线程都有个私有的本地工作内存,私有本地工作内存是jmm模型抽象概念,并不是真实存在的,她涵盖了缓存,协缓存区,寄存器以及其他的硬件和编译器的优化,本地内存中存储了该线程以读或写共享变量的拷贝的副本.
java内存模型 - 同步操作与规则:
Java内存模型解决的问题:
在多线程并发过程中,如何处理多线程读同步问题与可见性(多线程缓存与指令重排序)、多线程写同步问题与原子性(多线程竞争race condition)。
1、多线程读同步与可见性
可见性(共享对象可见性):线程对共享变量修改的可见性。当一个线程修改了共享变量的值,其他线程能够立刻得知这个修改
解决这个内存可见性问题你可以使用:
Java中的volatile关键字:volatile关键字可以保证直接从主存中读取一个变量,如果这个变量被修改后,总是会被写回到主存中去。Java内存模型是通过在变量修改后将新值同步回主内存,在变量读取前从主内存刷新变量值这种依赖主内存作为传递媒介的方式来实现可见性的,无论是普通变量还是volatile变量都是如此,普通变量与volatile变量的区别是:volatile的特殊规则保证了新值能立即同步到主内存,以及每个线程在每次使用volatile变量前都立即从主内存刷新。因此我们可以说volatile保证了多线程操作时变量的可见性,而普通变量则不能保证这一点。
Java中的synchronized关键字:同步快的可见性是由“如果对一个变量执行lock操作,将会清空工作内存中此变量的值,在执行引擎使用这个变量前需要重新执行load或assign操作初始化变量的值”、“对一个变量执行unlock操作之前,必须先把此变量同步回主内存中(执行store和write操作)”这两条规则获得的。
Java中的final关键字:final关键字的可见性是指,被final修饰的字段在构造器中一旦被初始化完成,并且构造器没有把“this”的引用传递出去(this引用逃逸是一件很危险的事情,其他线程有可能通过这个引用访问到“初始化了一半”的对象),那么在其他线程就能看见final字段的值(无须同步)
博客连接
https://www.bilibili.com/read/cv7892592/
https://zhuanlan.zhihu.com/p/29881777
注意JMM与JVM内存区域划分的区别: