shrunk是什么意思 assign是什么意思

思维导图

shrunk是什么意思 assign是什么意思

文章插图
面试官:讲讲什么是JMM
你要是整这个我可就不困了 。
shrunk是什么意思 assign是什么意思

文章插图
JMM就是Java内存模型(java memory model) 。因为在不同的硬件生产商和不同的操作系统下,内存的访问有一定的差异,所以会造成相同的代码运行在不同的系统上会出现各种问题 。所以java内存模型(JMM)屏蔽掉各种硬件和操作系统的内存访问差异,以实现让java程序在各种平台下都能达到一致的并发效果 。
Java内存模型规定所有的变量都存储在主内存中,包括实例变量,静态变量,但是不包括局部变量和方法参数 。每个线程都有自己的工作内存,线程的工作内存保存了该线程用到的变量和主内存的副本拷贝,线程对变量的操作都在工作内存中进行 。线程不能直接读写主内存中的变量 。
不同的线程之间也无法访问对方工作内存中的变量 。线程之间变量值的传递均需要通过主内存来完成 。
如果听起来抽象的话,我可以画张图给你看看,会直观一点:
shrunk是什么意思 assign是什么意思

文章插图
每个线程的工作内存都是独立的,线程操作数据只能在工作内存中进行,然后刷回到主存 。这是 Java 内存模型定义的线程基本工作方式 。
温馨提醒一下,这里有些人会把Java内存模型误解为Java内存结构,然后答到堆,栈,GC垃圾回收,最后和面试官想问的问题相差甚远 。实际上一般问到Java内存模型都是想问多线程,Java并发相关的问题 。
面试官:那JMM定义了什么
这个简单,整个Java内存模型实际上是围绕着三个特征建立起来的 。分别是:原子性,可见性,有序性 。这三个特征可谓是整个Java并发的基础 。
原子性
原子性指的是一个操作是不可分割,不可中断的,一个线程在执行时不会被其他线程干扰 。
面试官拿笔写了段代码,下面这几句代码能保证原子性吗?
int i = 2; int j = i; i++; i = i + 1;第一句是基本类型赋值操作,必定是原子性操作 。
第二句先读取i的值,再赋值到j,两步操作,不能保证原子性 。
第三和第四句其实是等效的,先读取i的值,再+1,最后赋值到i,三步操作了,不能保证原子性 。
JMM只能保证基本的原子性,如果要保证一个代码块的原子性,提供了monitorenter 和 moniterexit 两个字节码指令,也就是 synchronized 关键字 。因此在 synchronized 块之间的操作都是原子性的 。
可见性
可见性指当一个线程修改共享变量的值,其他线程能够立即知道被修改了 。Java是利用volatile关键字来提供可见性的 。当变量被volatile修饰时,这个变量被修改后会立刻刷新到主内存,当其它线程需要读取该变量时,会去主内存中读取新值 。而普通变量则不能保证这一点 。
除了volatile关键字之外,final和synchronized也能实现可见性 。
synchronized的原理是,在执行完,进入unlock之前,必须将共享变量同步到主内存中 。
final修饰的字段,一旦初始化完成,如果没有对象逸出(指对象为初始化完成就可以被别的线程使用),那么对于其他线程都是可见的 。
有序性
在Java中,可以使用synchronized或者volatile保证多线程之间操作的有序性 。实现原理有些区别:
volatile关键字是使用内存屏障达到禁止指令重排序,以保证有序性 。
synchronized的原理是,一个线程lock之后,必须unlock后,其他线程才可以重新lock,使得被synchronized包住的代码块在多线程之间是串行执行的 。
面试官:给我讲一下八种内存交互操作吧
好的,面试官,内存交互操作有8种,我画张图给你看吧:
shrunk是什么意思 assign是什么意思

文章插图
lock(锁定),作用于主内存中的变量,把变量标识为线程独占的状态 。
read(读取),作用于主内存的变量,把变量的值从主内存传输到线程的工作内存中,以便下一步的load操作使用 。
load(加载),作用于工作内存的变量,把read操作主存的变量放入到工作内存的变量副本中 。
use(使用),作用于工作内存的变量,把工作内存中的变量传输到执行引擎,每当虚拟机遇到一个需要使用到变量的值的字节码指令时将会执行这个操作 。
assign(赋值),作用于工作内存的变量,它把一个从执行引擎中接受到的值赋值给工作内存的变量副本中,每当虚拟机遇到一个给变量赋值的字节码指令时将会执行这个操作 。

推荐阅读