什么是缓存一致性问题?如何解决?
当程序在运行过程中,会将运算需要的数据从主存复制一份到cup的高速缓存当中,那么cpu进行计算时就可以直接从它的高速缓存读取数据和向其中写入数据,当运算结束后,再将高速缓存中的数据刷新到主存当中。举个简单的例子,比如下面这段代码:
i=i+1
当线程执行这个语句时,会先从缓存当中读取i的值,然后复制一份到高速缓存当中,然后CPU执行命令对i进行加1操作,然后将数据写入高速缓存。最后将高速缓存中的最新的值刷新到主存当中。
这个代码在单线程中运行时没有任何问题的,但是在多线程中运行就会有问题了。在多核CPU中,每条线程可能运行于不同的CPU中,因此每个线程运行时有自己的高速缓存(对单核CPU来说,其实也会出现这种问题,只不过是以线程调度的形式来分别执行的)。我们以多喝CPU为例。
可能存在下面一种情况:初始时,两个线程分别读取i的值存入各自所在的CPU的高速缓存当中,然后线程1进行加1操作,然后把i的最新值1写入到内存。此时线程2的高速缓存当中i的值还是0,进行加1操作之后,i的值为1,然后线程2把i的值写入内存。
最终结果i的值是1,而不是2.这就是缓存一致性问题。通常称这种被多个线程访问的变量为共享变量。
解决缓存一致性问题的方法有一下2种:
- 通过在总线加LOCK#锁的方式
- 通过缓存一致性协议
在早期的CPU当中,是通过在总线上加LOCK#锁的形式来解决缓存不一致的问题。因为CPU和其他部件进行通信都是通过总线来进行的,如果对总线加LOCK#锁的话,也就是说阻塞了其他CPU对其他部件访问,从而使得只有一个CPU能使用这个变量的内存。比如上面例子中,如果一个线程在执行i=i+1,如果在执行这段代码的过程中,在总线上发出了LOCK#锁的信号,那么只有等待这段代码完全执行完毕之后,其他CPU才能从变量i所在的内存读取变量,然后进行相应的操作。这样就解决了缓存不一致问题。
但是上面的方式会有一个问题,由于在锁住总线期间,其他CPU无法访问内存,导致效率低下。
所以就出现了缓存一致性协议。该协议保证了每个缓存中使用的共享变量的副本是一致的。它的核心思想是:当CPU向内存写入数据时,如果发现操作的变量是共享变量,即在其他CPU中也存在该变量的副本,会发出信号通知其他CPU将该变量的缓存置为无效状态,因此当其他CPU需要读取这个变量时,发现自己缓存中缓存行是无效的,那么它就会从内存重新读取。java中的volatile就是该协议的实现,volatile的实现原理可参见volatile底层实现。
什么是缓存一致性问题?如何解决?相关推荐
- 面试官:缓存一致性问题怎么解决?
关于Redis的其他的一些面试问题已经写过了,比如常见的缓存穿透.雪崩.击穿.热点的问题,但是还有一个比较麻烦的问题就是如何保证缓存一致性. 对于缓存和数据库的操作,主要有以下两种方式. 先删缓存,再 ...
- 内存模型是怎么解决缓存一致性的
转载自 内存模型是怎么解决缓存一致性的 在再有人问你Java内存模型是什么,就把这篇文章发给他这篇文章中,我们介绍过关于Java内存模型的来龙去脉. 我们在文章中提到过,由于CPU和主存的处理速度上 ...
- 白话Java基础—内存模型是怎么解决缓存一致性问题的?
内存模型是怎么解决缓存一致性问题的? 本系列呢,主要将我理解的Java基础内容,以比较白话的方式,解释出来,希望能帮助大家快速的理解一些概念. 文章目录 内存模型是怎么解决缓存一致性问题的? 一.缓存 ...
- 12 张图看懂 CPU 缓存一致性与 MESI 协议,真的一致吗?
本文已收录到 GitHub · AndroidFamily,有 Android 进阶知识体系,欢迎 Star.技术和职场问题,请关注公众号 [彭旭锐] 进 Android 面试交流群. 前言 大家好 ...
- cpu缓存一致性详解
原文链接: https://www.jianshu.com/p/c729f26b47f9 前言 在计算机中,计算机的指令都是由 CPU(Central Processing Unit,中央处理器)来执 ...
- 什么是缓存一致性问题?如何解决呢?
点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:牛人 20000 字的 Spring Cloud 总结,太硬核了~ 作者:MrHH 链接:https://www ...
- 4.什么是MESI缓存一致性协议?怎么解决并发的可见性问题?
MESI一致性协议 小陈:老王,上一章你让我看看MESI一致性协议,我大概了解了一下. 老王:哦,来说说你对MESI一致性协议的理解 小陈:MESI协议也叫做缓存一致性协议,主要是用来进行协调多核CP ...
- 数据库和缓存一致性的问题
经常看到有人问怎么解决数据库和缓存一致性的问题,这个问题我觉得是不要去解决. 如果你不信你先看我列的几种情况 假设 数据库一开始和缓存都是1元. 用户更新数据库的同时双写缓存. 1.双写不删 写库充值 ...
- 10 张图打开 CPU 缓存一致性的大门
前言 直接上,不多 BB 了. 正文 CPU Cache 的数据写入 随着时间的推移,CPU 和内存的访问性能相差越来越大,于是就在 CPU 内部嵌入了 CPU Cache(高速缓存),CPU Cac ...
最新文章
- Oracle简单的备份和恢复-导出和导入(1)
- java soa例子_哪位大牛能举个实例讲下SOA与传统架构的区别?
- 不用任何程序就可锁住和隐藏你的文件
- 软件工程师怎样减轻工作过程中遇到的压力
- [UI] MFD UI kit
- dijkstra+堆优化
- 一分钟学会Git操作流程
- HDU 4283 You Are the One
- 为 Windows 用户准备的简明 Linux 词汇表
- java mdt_java – MST映射到当前是MDT的joda中的Denver时区.这是joda DateTimeZone中的错误吗?...
- 最大公约数和最小公倍数的关系
- 计算机无法安装MUMU模拟器,电脑手机模拟器,详细教您电脑手机模拟器MuMu模拟器怎么使用...
- 关于 用git clone 命令时报错RPC failed; curl 56 Recv failure....’ 的解决办法
- java 获取年和季度_java获取当前时间的年周月季度等的开始结束时间
- 用python一键生成动画(上)
- 可视化丨福尔摩斯探案集的数据分析
- 【报告分享】2021年小红书内容营销趋势洞察-千瓜(附下载)
- 网络天才网页中文版_akinator中文版在线玩
- 计算机图像处理怎么学,计算机图像处理在全息学中的应用
- 使用Mob进行短信验证码发送
热门文章
- 使用WDK的ChkINF工具验证INF文件语法
- 紫书例题 11-6 Uva658 SPFA,血坑
- 怎么让网页变成黑白色?
- linux查看防火墙状态
- Created with Cocos丨超好玩的人气 2D/3D 游戏大合集,根本停不下来!
- 自媒体神器 Previs Shot 使用指南
- 一个IP地址是由四个字节(每个字节8个位)的二进制码组成。请将32位二进制码表示的IP地址转换为十进制格式表示的IP地址输出。如果输入的数字不足32位或超过32位或输入的数字中有非0和1的数字时输出“
- Tech 助力Fin ,大数据风控系统赋能掌众金服!
- 初一数学计算机教案,鲁教版初一上数学电子教案(已整理).doc
- 流媒体系统的开发跟运维