Java内存模型

Java虚拟机规范中定义一种Java内存模型来屏蔽各种硬件和操作系统的内存访问差异,以实现Java在各种平台都能达到一致的内存访问效果。
引发问题:
内存模型必须保证多线程并发内存访问不会出现问题。
定义程序中各个变量的访问规则,即在虚拟机中将变量存储到内存和从内存中读取变量的底层细节,此处的变量不包含局部变量与方法参数,因为他们是线程私有的,不会被共享,也不存在线程之间的可见性问题,所以不受内存模型影响。

Java内存模型规定所有变量都存储在住内存(虚拟机内存的一部分)中,每条线程都有自己的工作内从。线程的工作内存中保存了被该线程使用到的变量的住内存的副本,线程对变量的所有操作都必须在自己的工作内存中,不同的线程也无法访问对方的工作 内存。线程间变量值的传递必须通过住内存。

JMM抽象结构模型

CPU的处理速度和主存的读写速度不是一个量级的,为了平衡这种巨大的差距,每个CPU都会有自己的高速缓存。类比,共享变量会先放在主存中,每个线程都有属于自己的工作内存,并且会把位于主存中的共享变量拷贝到自己的工作内存,之后的读写操作均使用位于工作内存的变量副本,并在某个时刻将工作内存的变量副本写回到主存中去,下图是线程 ,工作内存,主内存三者交互关系图

image.png

内存间交互操作

JMM定义了8中澳做来完成变量 在工作内存和主内存之间的传递,虚拟机在实现时必须保证这8种操作都是原子的不可再分的。

命令 作用区域 描述
lock 锁定 主内存 将一个变量标识为一条线程独占状态
unlock 解锁 主内存 将一个处于锁定状态的变量释放出来,释放后的变量才能被其他线程使用
read 读取 主内存 将主内存的变量值传输到工作内存,以便之后load操作
load 载入 工作内存 将read从主内存读取过来的变量值放入到工作内存的变量副本中
use 使用 工作内存 将工作内存中的一个变量值传递给执行引擎
每当虚拟机遇到一个需要使用变量值的字节码指令时会执行这个操作
assign 赋值 工作内存 将从执行引擎接收到的变量值赋给工作内存的变量
每当虚拟机遇到一个给变量赋值的字节码指令时会执行这个操作
store 存储 工作内存 将工作内存中的变量值传送到主内存,以便之后write操作
write 写入 主内存 将store从工作内存中得到的变量值放到主内存的变量中

如果要把一个变量从主内存复制到工作内存中,则必须顺序的执行read 和load操作,如果把变量值从工作内存中同步回主内存,则必须顺序的执行store 和 write操作,值得注意的是Java内存模型只规定了这两个操作必须按照顺序执行,但是没有保证连续执行。也就是,read load,store write 之间是可以插入其他指令的。除此之外,JMM还规定了执行上述8种操作必须满足如下规则:

  • 一个变量同一时刻只允许一个线程对其进行lock操作,但同一个线程可以对同一个变量进行多次lock,并且需要执行相应数量的unlock操作,才能释放该变量的锁。
  • 一个变量被lock之后,会清空工作内存中的变量副本,在执行引擎使用这个变量之前,需要重新执行load或assigin操作初始化该变量的值
  • 一个变量没有被lock,则不允许被unlock,也不允许unlock其他线程锁定的变量
  • 一个变量在执行unlock之前,必须先同步到主内存,即执行了store操作
  • 不允许 read load store write 单一出现
  • 变量必须从主内存诞生,不允许在工作内存中直接使用未被初始化的变量
  • 变量不允许没有任何原因的写回到主内存,即store之前必须执行过assgin操作
  • 不允许一个线程丢弃它最近的assign操作,即变量在工作内存中改变了之后必须同步到主内存中

原子性、可见性与有序性

Java内存模型是围绕着在并发过程中如何处理 原子性,可见性和有序性这三个特征来建立的

  • 原子性
    一个或者多个操作在 CPU 执行的过程中不被中断的特性称为原子性
    由JMM来直接保证原子性变量包括read、load、assigin、use、store、write,我们大致可以认为基本数据类型的访问读写是具备原子性的(double 和long 是非原子性协定)。
    如果一个应用需要更大范围的原子性保证,JMM提供了更高层次的字节码指令monitorenter与monitorexit 隐式的使用 lock与unlock操作,而这两个字节码指令映射到java代码中就是synchronized关键字,因此 synchronized块中的操作也具备原子性。
    可见性
    可见性指一个线程修改了共享变量的值,另一个线程能够立刻得知这个修改
    Java中 volatile ,synchronized ,final 关键字能够实现可见性。
    volatile实现可见性:volatile共享变量保证在工作内存中改变后的新值能够立刻写回到主存中,并且会使其他cpu里缓存了该内存地址的数据无效(在多处理器下,为了保证各个处理器的缓存一致,需要实现缓存一致性协议,每个处理器通过嗅探在总线上传播的数据来检查自己缓存的有效性,当发现自己缓存行对应的内存地址被修改,就会将当前处理器的缓存设置成失效,当再次使用该变量的时候就会从主存读到工作内存)
    synchronized实现可见性:synchronized变量同一时刻只允许同一线程进行访问,在执行unlock操作前必须执行write操作,在执行lock后将工作内存中的该变量失效,在使用前从主存中获取。
    final实现可见性:被final修饰的字段在构造器中一旦初始化完成,并且构造器没有把this的引用传递出去,那其他线程就可以看到final字段的值。

    有序性
    在本线程内观察,所有操作都是有序的,即线程内表现为串行的语义
    在一个线程中观察另一个线程,所有操作都是无序的,指指令重排和工作内存,主内存同步延迟现象
    Java中 volatile 与 synchronized 关键字实现了有序性
    volatile 关键字禁止指令重排
    synchronized 一个变量同一时刻只允许一条线程对其进行lock操作。

先行发生原则

如果A操作先行发生与B操作,则A操作的发生的影响能被B观察到。
如果线程A先行于B,B先行于C,则A先行于C。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,128评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,316评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,737评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,283评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,384评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,458评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,467评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,251评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,688评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,980评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,155评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,818评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,492评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,142评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,382评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,020评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,044评论 2 352

推荐阅读更多精彩内容