java内存模型

1.内存模型(JMM)

1.1什么是Java内存模型?

Java内存模型将内存分为主内存和工作内存两大部分;主内存用来存储线程之间共享数据,工作内存则是每个线程独享内存,存储对应线程使用到的共享数据副本

java内存模型JMM.png

Java内存模型和硬件中的多核CPU、CPU对应的缓存(1级缓存、2级缓存、3级缓存)、以及内存之间的设计异曲同工;CPU的每个核可以跑不通的线程,由于CPU执行指令速度远远大于内存读写速度,为了平衡两者差距,高速缓存就引入了计算机体系中,高速缓存位于CPU和内存之间;读写速度能力 CPU>L1>L2>L3>Memory(越靠近CPU侧,处理能力越高,读写越快);存储数据能力Memory>L3>L2>L1>CPU(越靠近Memory侧,存储能力越强);计算机执行程序时,CPU执行程序时,会频繁的使用数据从内存中拷贝到缓存中,这样CPU运算时可以更快的读取到运算的数据;当CPU运算结束,又将数据从高速缓存写回到内存中。

1.2.内存模型中工作内存和主内存的区别?
  • 主内存:所有线程共享的区域;存储共享数据的区域
  • 工作内存:线程私有的存储区域;主要存储线程使用的主内存中数据的副本
1.3.内存模型带来什么问题

工作内存和主内存中数据不一致问题

  1. 原子性

    线程1 和 线程2 并发执行 +1操作,并同步到主内存中

内存模型-原子性.png
  1. 可见性

    内存模型-可见性.png
  1. 重排序
public class Test{
  private int a = 0;
  private int b = 0;
  
  public void setAAndB() {
    a = 1;
    b = 2;
  }
  
  public void changeB() {
    if (a == 1) {
      b = 4;
    }
    System.out.println("b=" + b);
  }
}
内存模型重排序.png
1.4.volatile关键字有哪些语义

volatile主要面对JMM带来的问题(工作内存和主内存中数据不一致)而产生的一种解决方案

语义有

  1. volatile修饰的变量具有可见性
  2. volatile修饰的变量读写原子性(如32位系统上的Long变量)
  3. volatile修饰的变量,读写操作不会参与前后指令的重排序

具体理解

  1. volatile修饰的变量具有可见性

    对于一个volatile变量的读,总能看到(任意线程)对这个volatile变量最后的写入值

    写:当写一个volatile变量时,JMM会把该线程对应的本地内存中的共享变量值刷新到主内存中

    读:当读一个volatile变量时,JMM会把该线程对应的本地内存置为无效,重新从主内存中读取共享变量到工作内存中

    volatile可见性.png
  1. volatile修饰的变量读写原子性(单步操作)

    对于任意单个volatile变量的读、写具有原子性;但是对于i++这种复合操作不具有原子性

  2. volatile修饰的变量,读写操作不会参与前后指令的重排序

    是否可以重排序 第二个操作 第二个操作 第二个操作
    第一个操作 普通读/写 volatile读 volatile写
    普通读/写 不可以重排序
    volatile读 不可以重排序 不可以重排序 不可以重排序
    volatile写 不可以重排序 不可以重排序

    总结:

    • 第一个操作为volatile读时,不管第二个操作是什么,都不可以重排序
    • 第二个操作为volatile写时,不管第一个操作是什么,都不可以重排序
    • 第一个操作为volatile写,第二个操作为volatile读时,不可以重排序
1.5.volatile是怎么实现的

还是围绕三个语义来看

  1. 可见性

    在写入volatile变量的时候,JVM会向CPU发送Lock指令,Lock指令具有两个作用

    • 将当前工作内存中数据写入到主内存中
    • 涉及其他线程对应的CPU核中缓存的数据设置无效(CPU消息一致性协议和嗅探功能),之后读会重新重主内存拉取最新数据
  2. 原子性(读写原子性)

    线程是CPU调度的基本单位。CPU有时间片的概念,会根据不同的调度算法进行线程调度。当一个线程获得时间片之后开始执行,在时间片耗尽之后,就会失去CPU使用权。所以在多线程场景下,由于时间片在线程间轮换,就会发生原子性问题。

    为了保证原子性,需要通过字节码指令monitorenter和monitorexit,但是volatile和这两个指令之间是没有任何关系的。

    所以,volatile是不能保证(复合操作)原子性的

  3. 重排序(有序性)

    主要靠内存屏障(硬件层面的指令,它可以禁止屏障前后的指令进行重排序)

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

推荐阅读更多精彩内容