a=a+1背后的内存模型和CPU高速缓存
学过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高速缓存的更多相关文章
- 黑马-----内存模型和volatile详解
黑马程序员:Java培训.Android培训.iOS培训..Net培训 JAVA线程-内存模型和volatile详解 一.单核内存模型 1.程序运行时,将临时数据存放到Cache中 2.将CPU计算所 ...
- Java内存模型和JVM内存管理
Java内存模型和JVM内存管理 一.Java内存模型: 1.主内存和工作内存(即是本地内存): Java内存模型的主要目标是定义程序中各个变量的访问规则,即在JVM中将变量存储到内存和从内存中取 ...
- 【Java】JMM内存模型和JVM内存结构
JMM内存模型和JVM内存结构 JAVA内存模型(Java Memory Model) Java内存模型,一般指的是JDK 5 开始使用的新的内存模型,主要由JSR-133: JavaTM Memor ...
- Java 内存模型和 JVM 内存结构真不是一回事
这两个概念估计有不少人会混淆,它们都可以说是 JVM 规范的一部分,但真不是一回事!它们描述和解决的是不同问题,简单来说, Java 内存模型,描述的是多线程允许的行为 JVM 内存结构,描述的是线程 ...
- 并发一:Java内存模型和Volatile
并发一:Java内存模型和Volatile 一.Java内存模型(JMM) Java内存模型的主要目标是定义程序中各个变量的访问规则,即在虚拟机中将变量存储到内存和在内存中取出变量的底层细节,是围绕着 ...
- JVM内存结构、Java内存模型和Java对象模型
Java作为一种面向对象的,跨平台语言,其对象.内存等一直是比较难的知识点.而且很多概念的名称看起来又那么相似,很多人会傻傻分不清楚.比如本文要讨论的JVM内存结构.Java内存模型和Java对象模型 ...
- JAVA内存模型和Happens-Before规则
前言 上一篇文章王子给大家介绍了并发编程中比较关心的三个核心问题,可见性.有序性和原子性. 今天我们继续来探索并发编程的内容,聊一聊JAVA的内存模型和Happens-Before规则. JAVA内存 ...
- 基于JVM原理、JMM模型和CPU缓存模型深入理解Java并发编程
许多以Java多线程开发为主题的技术书籍,都会把对Java虚拟机和Java内存模型的讲解,作为讲授Java并发编程开发的主要内容,有的还深入到计算机系统的内存.CPU.缓存等予以说明.实际上,在实际的 ...
- Java线程角度的内存模型和volatile型变量
内存模型的目标是定义程序中各个变量的访问 规则,即在虚拟机中将变量(包括实例字段,静态字段和构成数组对象的元素,不包括局部变量与方法参数,因为后者是线程私有的)存储到内存和从内存中取出变量这样的底层细 ...
随机推荐
- 【代码备份】原图降采样后进行NLM滤波
文件路径: 滤波算法main.m: %% 测试函数 %NLM滤波及滤波与 clc,clear all,close all; ima_ori=double(imread('F:\Users\****n\ ...
- Java Print 打印
Java 原生的API中有Print,使用Print可以操作打印机进行打印操作,获取打印机属性,下面是代码 打印程序(静默打印) package com.boci.PrintPDF; import j ...
- iOS实现截屏 并合适保存
本文转载至:http://blog.csdn.net/zeng11088/article/details/8664510 分类: UIImageView2013-03-12 16:42 122人阅读 ...
- Spring JDBC样例
这里介绍一下通过Spring JDBC的方式进行数据库的增删改查的操作.在进行程序的编写之前我们需要在本地MySQL数据库中创建一张User表,如下所示: create database user_d ...
- 递归删除资源树 Ztree
前言 最近项目里有这么一个需求:现在有一个用Ztree编写的资源树,当删除资源树的某个节点时,则将此节点下面的所有节点全部删除,这里显然就用到了递归:若此节点被删除后无其它的兄弟节点了,我们还需要将其 ...
- Oracle 数存储——物理结构
Oracle存储——逻辑结构 Oracle 数据库存储物理结构 物理存储结构是实际的数据存储单元,对应于操作系统文件. oracle数据库就是由驻留在服务器的磁盘上的这些操作系统文件组成的. 物理存储 ...
- Educational Codeforces Round 25 E. Minimal Labels&&hdu1258
这两道题都需要用到拓扑排序,所以先介绍一下什么叫做拓扑排序. 这里说一下我是怎么理解的,拓扑排序实在DAG中进行的,根据图中的有向边的方向决定大小关系,具体可以下面的题目中理解其含义 Educatio ...
- Every write operation executed on a document, deletes included
Delete API | Elasticsearch Reference [6.5] | Elastic https://www.elastic.co/guide/en/elasticsearch/r ...
- ctf-HITCON-2016-houseoforange学习
目录 堆溢出点 利用步骤 创建第一个house,修改top_chunk的size 创建第二个house,触发sysmalloc中的_int_free 创建第三个house,泄露libc和heap的地址 ...
- good blog
https://blog.csdn.net/fgf00/article/details/52793739