学过JAVA的人都知道,程序运行过程中的临时数据,都是从外部存储设备调入内存(物理内存)中,再进行读写操作的。而计算机在执行程序时,对程序的每条指令都是在CPU中执行的,而指令的执行,势必涉及到对数据的读写操作。

  于是就产生了这样一个问题,CPU指令的执行速度是很快的,但是从内存中读取和写入数据的速度却是比较慢的。如果对数据的任何操作,都需要CPU和内存打交道,而由于内存的读取速度远远慢于CPU的执行速度,这样就大大降低了CPU执行的效率,于是就有了CPU高速缓存的概念。

  CPU,CPU高速缓存,内存协同工作过程

  1、程序运行过程,会将所需要操作的业务数据加载到内存中,并复制一份到CPU的高速缓存中。

  2、CPU指令执行时,直接从CPU高速缓存中读取和写入数据,提高工作效率。

  3、CPU运算结束后,将结果写入CPU高速缓存,此时再同步至内存中。

  

  多线程场景下a = a + 1的难题

  程序执行该代码时,JVM进程中首先开启一个线程,从外部存储设备中加载class文件至内存中并赋予了a初始值,并将a值复制一份存储至CPU高速缓存中。运算时,CPU指令首先从高速缓存中读取a值,进行+1操作后将结果写入高速缓存中,再由高速缓存同步至内存中,于是一个加法运算的全过程就顺利完成了。

  这个代码在单线程的场景中,是没有任何问题的。但如果是运行在多核CPU的多线程场景下就会出问题了。

  在多核CPU下,每个线程都可能拥有自己独立的CPU,每个线程运行时都有自己的CPU高速缓存,这样就容易造成计算结果的脏数据。

  假设a在JVM加载初始化过程被赋值为0,线程A和B同时执行a = a + 1的操作,此时我们预期的结果可能都是a最终的结果为2。

  但是,如果线程A,B同时从内存中复制了a值至各自的CPU高速缓存中,A执行完了a = 1写入自己线程的缓存,再同步回内存,B也如此。这样一来,最终a的值就定格在了1,这是和预期结果所相悖的。也就是说,在多CPU,多线程编程的场景下,很有可能存在计算结果为脏数据的现象。

  为解决该难题,就需要使用volatile关键字对变量进行修饰了,至于volatile关键字为啥有此神奇功效,请看本博客的《深入剖析volatile关键字》。

  

a=a+1背后的内存模型和CPU高速缓存的更多相关文章

  1. 黑马-----内存模型和volatile详解

    黑马程序员:Java培训.Android培训.iOS培训..Net培训 JAVA线程-内存模型和volatile详解 一.单核内存模型 1.程序运行时,将临时数据存放到Cache中 2.将CPU计算所 ...

  2. Java内存模型和JVM内存管理

    Java内存模型和JVM内存管理   一.Java内存模型: 1.主内存和工作内存(即是本地内存): Java内存模型的主要目标是定义程序中各个变量的访问规则,即在JVM中将变量存储到内存和从内存中取 ...

  3. 【Java】JMM内存模型和JVM内存结构

    JMM内存模型和JVM内存结构 JAVA内存模型(Java Memory Model) Java内存模型,一般指的是JDK 5 开始使用的新的内存模型,主要由JSR-133: JavaTM Memor ...

  4. Java 内存模型和 JVM 内存结构真不是一回事

    这两个概念估计有不少人会混淆,它们都可以说是 JVM 规范的一部分,但真不是一回事!它们描述和解决的是不同问题,简单来说, Java 内存模型,描述的是多线程允许的行为 JVM 内存结构,描述的是线程 ...

  5. 并发一:Java内存模型和Volatile

    并发一:Java内存模型和Volatile 一.Java内存模型(JMM) Java内存模型的主要目标是定义程序中各个变量的访问规则,即在虚拟机中将变量存储到内存和在内存中取出变量的底层细节,是围绕着 ...

  6. JVM内存结构、Java内存模型和Java对象模型

    Java作为一种面向对象的,跨平台语言,其对象.内存等一直是比较难的知识点.而且很多概念的名称看起来又那么相似,很多人会傻傻分不清楚.比如本文要讨论的JVM内存结构.Java内存模型和Java对象模型 ...

  7. JAVA内存模型和Happens-Before规则

    前言 上一篇文章王子给大家介绍了并发编程中比较关心的三个核心问题,可见性.有序性和原子性. 今天我们继续来探索并发编程的内容,聊一聊JAVA的内存模型和Happens-Before规则. JAVA内存 ...

  8. 基于JVM原理、JMM模型和CPU缓存模型深入理解Java并发编程

    许多以Java多线程开发为主题的技术书籍,都会把对Java虚拟机和Java内存模型的讲解,作为讲授Java并发编程开发的主要内容,有的还深入到计算机系统的内存.CPU.缓存等予以说明.实际上,在实际的 ...

  9. Java线程角度的内存模型和volatile型变量

    内存模型的目标是定义程序中各个变量的访问 规则,即在虚拟机中将变量(包括实例字段,静态字段和构成数组对象的元素,不包括局部变量与方法参数,因为后者是线程私有的)存储到内存和从内存中取出变量这样的底层细 ...

随机推荐

  1. kettle两表内链接的查询结果与sql语句的查询结果不符合?

    1.教师表输入 2.学生表 查 3.学生表中查出的教师id进行排序 5.教师表中查出的同样也对教师的id进行排序 6.进行左连接 总结: 进行连接的时候的关键是同样对教师的id进行先排序

  2. selenium:chromedriver与chrome版本的对应关系

    转自:http://blog.csdn.NET/huilan_same/article/details/51896672 再使用selenium打开chrome浏览器的时候,需要用chromedriv ...

  3. 【BZOJ】1692 & 1640: [Usaco2007 Dec]队列变换(后缀数组+贪心)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1692 http://www.lydsy.com/JudgeOnline/problem.php?id ...

  4. WinDbg 解决Font.ToLogFont AccessViolationExcetion

    有个程序总是在windows 2003 server 异常退出. 并且,  查看调用栈也肯奇怪, 应该是很正常的调用. 怀疑是堆溢出. 开启heap trace : C:\Program Files\ ...

  5. [WPF]实现密码框的密码绑定

    正如绑定TextBox控件的Text属性一样, 我们希望能够将PasswordBox空间的Password属性进行绑定, 比如在MVVM模式中,这似乎是必须的, 但可惜的是, Password属性是不 ...

  6. python3----练习题(图片转字符画)

    import argparse from PIL import Image def parse_param(): parser = argparse.ArgumentParser() # 命令行输入参 ...

  7. UVA 548(二叉树重建与遍历)

    J - Tree Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Ap ...

  8. 阿里云CentOS6.8云服务器配置安全组规则

    前提:已经购买阿里云服务器,域名解析也完成了 需要对安全组规则进行配置,才能进行访问 1.进入阿里云首页https://www.aliyun.com/,如下图 2.进入控制台首页,如下图 3.在上图页 ...

  9. configChanges

    android中的组件Activity在manifest.xml文件中可以指定参数android:ConfigChanges,用于捕获手机状态的改变. 在Activity中添加了android:con ...

  10. Android之MessageQueue、Looper、Handler与消息循环

    在android的activity中有各种各样的事件,而这些事件最终是转换为消息来处理的.android中的消息系统涉及到: *  消息发送 *  消息队列 *  消息循环 *  消息分发 *  消息 ...