学过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. Linux 高频工具快速教程

    全书分为三个部分: 第一部分为基础篇,介绍我们工作中常用的工具的高频用法: 第二部分为进阶篇,介绍的工具更多的适合程序员使用,分为程序构建.程序调试及程序优化: 第三部分是工具参考篇,主要介绍实用工具 ...

  2. 【BZOJ】1058: [ZJOI2007]报表统计(splay+set)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1058 当复习一下splay.... 做法很简单..... 观察得知每一次插入一个点只需要维护前后的绝 ...

  3. Swift AVFoundation 二维码扫描和生成

    项目最终不须要支持iOS6了(泪崩),在二维码扫描这一块,可以全然的放弃ZXing库,改用系统的AVFoundation了,拿swift写了个Demo,效果例如以下: github地址:点这里 有关A ...

  4. 返回flag

    //修改前namespace CleanCSharp.Errors.Dirty { public class SomeClass { public int DoSomeProcess(int? id) ...

  5. identity_insert---实验性插入大批量数据和分页存储过程

    OK,我们首先创建一数据库:data_Test,并在此数据库中创建一表:tb_TestTable 1create database data_Test --创建数据库data_Test 2use da ...

  6. 浅谈AutoResetEvent的用法

    using System;using System.Threading; namespace AutoResetEvent_Examples{    class MyMainClass    {    ...

  7. 解析IE, FireFox, Opera 浏览器支持Alpha透明的方法

    先请看如下代码: filter:alpha(opacity=50);       /* IE */  -moz-opacity:0.5;              /* Moz + FF */  op ...

  8. JavaWeb的编码问题

    http://blog.csdn.net/yuhaiqiang_123/article/details/51811419

  9. python3----scrapy(笔记)

    import scrapy import sys # import io # sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='gb ...

  10. Spring_day04--课程安排_回顾SSH框架知识点_SSH框架整合思想

    Spring_day04 上节内容回顾 今天内容介绍 回顾SSH框架知识点 Hibernate框架 Struts2框架 Spring框架 SSH框架整合思想 整合struts2和spring框架 Sp ...