目录
version:jdk1.8
JMM内存模型
Java Memory Model:Java内存模型
JMM是Java 虚拟机规范中所定义的一种内存模型。因为在不同的硬件生产商和不同的操作系统下,内存的访问有一定的差异,所以会造成相同的程序运行在不同的系统上会出现各种问题。因此 Java 内存模型屏蔽了各种硬件和操作系统的访问差异的,保证了 Java 程序在各种平台下对内存的访问都能保证一致的并发效果。
JMM 定义了线程和主内存之间的抽象关系:线程之间的共享变量存储在主内存中,每个线程都有一个私有的本地内存,本地内存中存储了该线程以读/写共享变量的副本
JMM与JVM内存区域模型
JMM与JVM内存区域的划分是不同的概念层次,更恰当说JMM描述的是一组规则,通过这组规则控制程序中各个变量在共享数据区域和私有数据区域的访问方式,JMM是围绕原子性,有序性、可见性展开。JMM与Java内存区域唯一相似点,都存在共享数据区域和私有数据区域,在JMM中主内存属于共享数据区域,从某个程度上讲应该包括了堆和方法区,而工作内存数据线程私有数据区域,从某个程度上讲则应该包括程序计数器、虚拟机栈以及本地方法栈。
缓存一致性协议(EMCI)
E:独占状态(互斥)
M:修改状态(修改)
S:共享状态
I:失效状态
MESI:当线程A获取CPU资源(变量O)时,从主内存中读取到需要使用的变量O后,此时可以理解为变量O状态为独占(E),当其他线程B也读取了该变量O时,所有缓存中该变量状态都改为(S),当线程A通过CPU写变量值时,A线程中变量O的状态为(M),与此同时如果发现操作的变量O是共享变量,即在其他CPU(B线程使用的CUP资源)中也存在该变量O的副本,会发出信号通知其他CPU将该变量的缓存行置为无效状态(i),因此当其他CPU需要读取这个变量时,就会从内存重新读取。
线程间通信方式
1.volatile是轻量级的同步机制,volatile保证变量对所有线程的可见性,不保证原子性。
2.synchronized保证线程对变量访问的可见性和排他性。
volatile
- 当对volatile变量进行写操作的时候,JVM会向处理器发送一条LOCK前缀的指令,将该变量所在缓存行的数据写回系统内存。
- 由于缓存一致性协议,每个处理器通过嗅探在总线上传播的数据来检查自己的缓存是不是过期了,当处理器发现自己缓存行对应的内存地址被修改,就会将当前处理器的缓存行置为无效状态,当处理器对这个数据进行修改操作的时候,会重新从系统内存中把数据读到处理器缓存中。
volatile关键字的两个作用:
- 保证了不同线程对共享变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。
- 禁止进行指令重排序。
指令重排序是JVM为了优化指令,提高程序运行效率,在不影响单线程程序执行结果的前提下,尽可能地提高并行度。Java编译器会在生成指令系列时在适当的位置会插入内存屏障指令来禁止处理器重排序。插入一个内存屏障,相当于告诉CPU和编译器先于这个命令的必须先执行,后于这个命令的必须后执行。对一个volatile字段进行写操作,Java内存模型将在写操作后插入一个写屏障指令,这个指令会把之前的写入值都刷新到内存。
- volatile使用
/** * 修饰静态成员变量 */ static volatile String str1; /** * 修饰成员变量 */ volatile String str2;
个人基于源码分析,学习总结分享,如有疑问,请联系博主,蟹蟹!