1 我们先了解CPU缓存

CPU缓存为了解决CPU运算速度与内存读写速度不匹配的问题,因为CPU运算速度要比内存读写速度快得多

  • 一次主内存的访问通常在几十到几百个时钟周期
  • 一次L1高速缓存的读写只需要1~2个时钟周期
  • 一次L2高速缓存的读写也只需要数十个时钟周期

CPU大多数情况下读写都不会直接访问内存,取而代之的是CPU缓存,CPU缓存是位于CPU与内存之间的临时存储器(简单理解为寄存器),它容量比内存小得多但是交换速度却比内存快得多。而缓存中的数据是内存中的一小部分数据,但这一小部分是短时间内CPU即将访问的,当CPU调用大量数据时,就可先从缓存中读取,从而加快读取速度

CPU缓存可分为:一级缓存(是与CPU结合最为紧密的CPU缓存二级缓存三级缓存,每一级缓存中所存储的数据全部都是下一级缓存中的一部分

CPU要读取数据时,首先从一级缓存中查找,如果没有再从二级缓存中查找,如果还是没有再从三级缓存中或内存中查找。一般来说每级缓存的命中率大概都有80%左右,只剩下20%的总数据量才需要从二级缓存、三级缓存或内存中读取。

CPU执行计算的过程如下:

  • 程序以及数据被加载到主内存
  • 指令和数据被加载到CPU缓存
  • CPU执行指令,把结果写到高速缓存
  • 高速缓存中的数据写回主内存

2 总线锁

每个CPU都有一级缓存,但是,我们却无法保证每个CPU的一级缓存数据都是一样的,如何保证各个CPU缓存中的数据是一致的。就是CPU的缓存一致性问题

1)总线锁

一种处理一致性问题的办法是使用Bus Locking(总线锁)。当一个CPU对其缓存中的数据进行操作的时候,往总线中发送一个Lock信号。 这个时候,所有CPU收到这个信号之后就不操作自己缓存中的对应数据了,也就是把数据直接写入主内存,当操作结束,释放锁以后,所有的CPU就去内存中获取最新数据更新

3 volatile如何保证可见性

我们把有volatile修饰的变量编译成部分汇编,这里有个lock指令

0x01a3de24: lock addl $0X0,(%esp);

如果是写操作,cpu会发出一个lock指令,CUP会把数据直接写到到主内存

如果是读操作,cpu会发出一个unlock指令, 所有的CPU就去内存中获取最新数据更新

4 volatile如何保证指令重排序

现代的操作系统都是多处理器.而每一个处理器都有自己的缓存,并且这些缓存并不是实时都与内存发生信息交换.这样就可能出现一个cpu上的缓存数据与另一个cpu上的缓存数据不一致的问题.而这样在多线程开发中,就有可能导致出现一些异常行为.
而操作系统底层为了这些问题,提供了一些内存屏障用以解决这样的问题.目前有4种屏障.

  • LoadLoad屏障:对于这样的语句Load1; LoadLoad; Load2,在Load2及后续读取操作要读取的数据被访问前,保证Load1要读取的数据被读取完毕。
  • StoreStore屏障:对于这样的语句Store1; StoreStore; Store2,在Store2及后续写入操作执行前,保证Store1的写入操作对其它处理器可见。
  • LoadStore屏障:对于这样的语句Load1; LoadStore; Store2,在Store2及后续写入操作被刷出前,保证Load1要读取的数据被读取完毕。
  • StoreLoad屏障:对于这样的语句Store1; StoreLoad; Load2,在Load2及后续所有读取操作执行前,保证Store1的写入对所有处理器可见。

在每个volatile写操作前插入StoreStore屏障,在写操作后插入StoreLoad屏障;
在每个volatile读操作前插入LoadLoad屏障,在读操作后插入LoadStore屏障;

由于内存屏障的作用,避免了volatile变量和其它指令重排序 

参考链接:

https://crowhawk.github.io/2018/02/10/volatile/

https://www.jianshu.com/p/ef8de88b1343

https://my.oschina.net/LucasZhu/blog/1537330

Java之volatile如何保证可见性和指令重排序相关推荐

  1. 说说Java中原子性,可见性与指令重排序的理解

    原子性:就是读数据,处理数据,写数据 这三个步骤不能被终止,或者打断:就是不能被线程调度器中断,切换线程. 这样,才能保证,原子操作在线程切换,并行处理上保证数据地顺序累加处理. 可见性:是Jvm较为 ...

  2. JVM学习--(二)内存模型、可见性、指令重排序

    我们将根据JVM的内存模型探索java当中变量的可见性以及不同的java指令在并发时可能发生的指令重排序的情况. 内存模型 首先我们思考一下一个java线程要向另外一个线程进行通信,应该怎么做,我们再 ...

  3. JVM并发机制探讨—内存模型、内存可见性和指令重排序

    并发本来就是个有意思的问题,尤其是现在又流行这么一句话:"高帅富加机器,穷矮搓搞优化".从这句话可以看到,无论是高帅富还是穷矮搓都需要深入理解并发编程,高帅富加多了机器,需要协调多 ...

  4. Java指令屏障_指令重排序和内存屏障

    sap hana计算技术项目实战指南内存 61元 (需用券) 去购买 > 一.指令重排序 指令重排序分为三种,分别为编译器优化重排序.指令级并行重排序.内存系统重排序.如图所示,后面两种为处理器 ...

  5. 由Java引起的指令重排序思考

    背景 问题出现 最近遇到了一个NullPointerException,虽然量不大,但是很怪异,大致长这个样子 这是个什么空指针?居然说我LinkedList.iterator().hasNext() ...

  6. 【Java 并发编程】线程指令重排序问题 ( 指令重排序规范 | volatile 关键字禁止指令重排序 )

    文章目录 总结 一.指令重排序规范 二.指令重排序示例 总结 Java 并发的 333 特性 : 原子性 : 每个操作都是 不可拆分的原子操作 ; 在线程中进行 a++ 就不是原子操作 , 该操作分为 ...

  7. Java的多线程机制系列:(四)不得不提的volatile及指令重排序(happen-before)

    一.不得不提的volatile volatile是个很老的关键字,几乎伴随着JDK的诞生而诞生,我们都知道这个关键字,但又不太清楚什么时候会使用它:我们在JDK及开源框架中随处可见这个关键字,但并发专 ...

  8. volatile如何保证可见性

    volatile如何保证可见性? 我们都知道volatile具有可见性和有序性,但是不保证原子性. 这篇文章主要是看一下volatile如何保障可见性的. 我们知道一般我们在使用多线程的过程中,为了保 ...

  9. java重排序_Java synchronized 能防止指令重排序吗?

    @ZealTalk 说的是 synchronized 可以防止指令重排,这个观点不对的,也欢迎回答的各位来讨论 synchronized 的有序性 来讨论这个问题先,先看看 Java 里的操作无序现象 ...

最新文章

  1. 在dw中如何调试html代码,如何在 Dreamweaver 中优化和调试代码 - Dreamweaver 用户指南...
  2. beyond compare4过期解决方法_面试必备:缓存穿透、雪崩解决方案及缓存击穿的四种解决方案...
  3. 产品认知:真正厉害的产品经理,都是“本质思维”的高手
  4. 关于有多个Fragment中的textview跑马灯问题
  5. Mybatis 一对多 简单映射配置
  6. mysql语句二级查询_mysql_2 基本查询语句
  7. struts2面试整理
  8. 电源管理与驱动设计笔记
  9. nginx 负载均衡 404_Nginx+.Net Core实现项目负载均衡
  10. 获取当前时间---年月日时分秒------iOS
  11. 【转】那些令人喷饭的注释
  12. centos6 revive-adserver
  13. UE4影视特效学习资源整理
  14. 如何筹办一场千人技术峰会?
  15. Ubuntu中的zip / unzip 和 rar / unrar 命令:压缩 / 解压 zip 和 rar 文件
  16. java日期计算天数_Java 两个日期间的天数计算
  17. 几张思维导图告诉你搜索引擎优化(SEO)核心点
  18. 虚拟货币套利怎么处理
  19. 在网上看到一篇很让人心水的三行情书,由此引发的种种
  20. 学习php开发难吗,PHP开发自学难吗,PHP自学要多长时间?

热门文章

  1. C# WPF MVVM开发框架Caliburn.Micro Screens, Conductors 和 Composition⑦
  2. 自主生态再进一步,龙芯中科完成.NET3.1-LoongArch64平台研发
  3. c# 通过内存映射实现文件共享内存
  4. 如何在 ASP.Net Core 中使用 HTTP.sys WebServer ?
  5. Dotnet Core异常处理的优雅实践
  6. ASP.NET Core分布式项目实战(运行Consent Page)--学习笔记
  7. 【在路上2】快递的运单轨迹
  8. 拿 C# 搞函数式编程 - 2
  9. 微软推出Python免费在线教程视频
  10. 我如何吸引Elastic创始人一起对高并发写入进行优化?