JMM(JAVA Memory Model) Java内存模型 和 volatile

1 篇文章 0 订阅
1 篇文章 0 订阅

JMM基础-计算机原理

在这里插入图片描述
计算 a+b
CPU读取一次内存 100ns,读取a,b花费200ns
CPU计算只用0.6ns
执行a+b绝大部分的时间是在等待读取内存
所以引入了高速缓存(一级、二级、三级)
多核CPU共享L3
在这里插入图片描述
L1速度最快 容量最小
在这里插入图片描述
为了提高运行速度 引入了cache
为了充分利用cache就提出了JMM

Java内存模型(JMM)

工作内存,主内存,两个抽象概念
工作内存:包括cpu内部的寄存器,高速缓存,还包括主内存(RAM)的一部分,很小一部分在主内存
主内存:也有小部分可能在寄存器和高速缓存
在这里插入图片描述
假如变量count进行累加操作
count在主内存里面
当任意线程要进行累加时,会把count放到线程独有的工作内存中去,每个操作count的线程中有count的副本
线程只允许对线程工作内存中的count进行操作,不允许直接操作主内存的变量
每个线程的工作内存是独享的
堆内存理解成主内存,栈内存理解成工作内存

在这里插入图片描述

JMM导致的并发安全问题

变量的可见性、原子性
count 初始值为 0
两个线程计算count = count + 1
结果应该是2 ,但结果可能是1
在这里插入图片描述
两个线程并不知道对方对线程进行了修改,看不到对方对count的修改,存在可见性问题

怎么解决可见性问题?

volatile

1.强迫从主内存中读取一次变量
2.每当把变量修改了后强迫马上刷新到主内存

volatile只能保证可见性

volatile不能解决我们的安全性问题,volatile只是强迫读写,问题在于计算过程不是一个原子操作

synchronized同时保证了可见性和原子性,synchronized的强度比volatile的强度大
volatile是JDK为我们提供的最最最轻量级的同步机制

可以把对volatile变量的单个读/写,看成是使用同一个锁对这些单个读/写操作做了同步
在这里插入图片描述
volatile变量自身具有下列特性:
可见性: 对一个volatile变量的读,总是能看到(任意线程)对这个volatile变量最后的写入。
原子性: 对任意单个volatile变量的读/写具有原子性,但类似于volatile++这种复合操作不具有原子性。

流水线和重排序:
cpu可以一次执行多条指令

do(){
    int a = 5 ;
    int b = 6 ;
    int c = 7 ;
    int d = a ;
    if( b == 6){
      d = b;
    }
}

我们的印象中cpu是顺序执行的,引入流水线和重排序后cpu可能一次性把四条全部执行了,可能在if(b == 6)之前 就把里面的 d = b 做了,把先算的东西放到内存中开辟的重排序缓存中,如果真的出现了if(b == 6)就把重排序缓存的结果直接放里面,不一定是if之后再算

intel cpu 最大可支持十级流水线,同一时刻可执行10条指令
安卓ARM架构三级流水线,同一时刻可执行3条指令

重排序改变了我们写代码顺序的含义 ,单线程一定符合我们的要求 ,多线程可能造成混乱
volatile可抑制重排序

volatile的应用场景:
只有一个线程写,多个线程读的时候,volatile用起来没有问题,可强迫写线程刷新到主内存,不然不知道什么时候才刷新到主内存,强迫读可以看到最新的变量(可见性)
多个线程对一个变量写时不能保证原子性
写操作之间没有任何关联,volatile用起来没有问题

JDK的并发工具中很多用:volatile + CAS 来替换synchronized
volatile 可以理解成无锁化编程

volatile的实现原理

有volatile变量修饰的共享变量进行写操作的时候会使用CPU提供的Lock前缀指令
1.将当前处理器缓存行的数据写回到系统内存
2.这个写回内存的操作会使在其他CPU里缓存了该内存地址的数据无效

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值