volatile保证可见性,原理是什么

2023-11-18

VOLATILE 只保证可见性(Java多线程内存可见性),并不保证原子性

可见性:一个线程对共享变量的修改,更够及时的被其他线程看到
原子性:即不可再分了,不能分为多步操作。比如赋值或者return。比如"a = 1;"和 "return a;"这样的操作都具有原子性。类似"a += b"这样的操作不具有原子性

线程操作变量
(1)线程对共享变量的所有操作都必须在自己的工作内存中进行,不能直接在主内存中读写
(2)不同线程之间无法直接访问其他线程工作内存中的变量,线程间变量值的传递需要通过主内存来完成。

现在服务器通常是多 CPU,更普遍的是,每块CPU里有多个内核,而每个内核都维护了自己的缓存,那么这时候多线程并发会存在缓存不一致性

解决:提供了总线锁定的机制,把CPU和内存的通信给锁住了,使得在锁定期间,其他处理器不能操作其他内存地址的数据,会导致开销比较大。
优化后提供了缓存一致性机制(缓存锁定)
缓存一致性:缓存一致性机制就整体来说,是当某块CPU对缓存中的数据进行操作了之后,就通知其他CPU放弃储存在它们内部的缓存,或者从主内存中重新读取

内存屏障

编译器和CPU会在不影响结果(这儿主要是根据数据依赖性)的情况下对指令重排序,使性能得到优化,但是实际情况里面有些指令虽然没有前后依赖关系,但是重排序之后影响到输出结果,这时候可以插入一个内存屏障,相当于告诉CPU和编译器限于这个命令的必须先执行,后于这个命令的必须后执行。
内存屏障的另一个作用是强制更新一次不同CPU的缓存,这意味着如果你对一个volatile字段进行写操作,你必须知道:一旦你完成写入,任何访问这个字段的线程将会得到最新的值;在你写入之前,会保证所有之前发生的事已经发生,并且任何更新过的数据值也是可见的,因为内存屏障会把之前的写入值都刷新到缓存

Volatile实现内存可见性是通过store和load指令完成的;也就是对volatile变量执行写操作时,会在写操作后加入一条store指令,即强迫线程将最新的值刷新到主内存中;而在读操作时,会加入一条load指令,即强迫从主内存中读入变量的值。ock前缀指令实际上相当于一个内存屏障。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

volatile保证可见性,原理是什么 的相关文章

  • Java 中等效的并行扩展

    我在 Net 开发中使用并行扩展有一些经验 但我正在考虑在 Java 中做一些工作 这些工作将受益于易于使用的并行库 JVM 是否提供任何与并行扩展类似的工具 您应该熟悉java util concurrent http java sun
  • java.lang.NoClassDefFoundError:org.apache.batik.dom.svg.SVGDOMImplementation

    我在链接到我的 Android LibGDX 项目的 Apache Batik 库时遇到了奇怪的问题 但让我们从头开始 在 IntelliJ Idea 中我有一个项目 其中包含三个模块 Main Android 和 Desktop 我强调的
  • Spring Batch 多线程 - 如何使每个线程读取唯一的记录?

    这个问题在很多论坛上都被问过很多次了 但我没有看到适合我的答案 我正在尝试在我的 Spring Batch 实现中实现多线程步骤 有一个包含 100k 条记录的临时表 想要在 10 个线程中处理它 每个线程的提交间隔为 300 因此在任何时
  • 为什么 i++ 不是原子的?

    Why is i Java 中不是原子的 为了更深入地了解 Java 我尝试计算线程中循环的执行频率 所以我用了一个 private static int total 0 在主课中 我有两个线程 主题 1 打印System out prin
  • 在画布上绘图

    我正在编写一个 Android 应用程序 它可以在视图的 onDraw 事件上直接绘制到画布上 我正在绘制一些涉及单独绘制每个像素的东西 为此我使用类似的东西 for int x 0 x lt xMax x for int y 0 y lt
  • Java - 将节点添加到列表的末尾?

    这是我所拥有的 public class Node Object data Node next Node Object data Node next this data data this next next public Object g
  • Java JDBC:更改表

    我希望对此表进行以下修改 添加 状态列 varchar 20 日期列 时间戳 我不确定该怎么做 String createTable Create table aircraft aircraftNumber int airLineCompa
  • 如何找到给定字符串的最长重复子串

    我是java新手 我被分配寻找字符串的最长子字符串 我在网上研究 似乎解决这个问题的好方法是实现后缀树 请告诉我如何做到这一点或者您是否有任何其他解决方案 请记住 这应该是在 Java 知识水平较低的情况下完成的 提前致谢 附 测试仪字符串
  • 在 HTTPResponse Android 中跟踪重定向

    我需要遵循 HTTPost 给我的重定向 当我发出 HTTP post 并尝试读取响应时 我得到重定向页面 html 我怎样才能解决这个问题 代码 public void parseDoc final HttpParams params n
  • 制作一个交互式Windows服务

    我希望我的 Java 应用程序成为交互式 Windows 服务 用户登录时具有 GUI 的 Windows 服务 我搜索了这个 我发现这样做的方法是有两个程序 第一个是服务 第二个是 GUI 程序并使它们进行通信 服务将从 GUI 程序获取
  • INSERT..RETURNING 在 JOOQ 中不起作用

    我有一个 MariaDB 数据库 我正在尝试在表中插入一行users 它有一个生成的id我想在插入后得到它 我见过this http www jooq org doc 3 8 manual sql building sql statemen
  • 从 127.0.0.1 到 2130706433,然后再返回

    使用标准 Java 库 从 IPV4 地址的点分字符串表示形式获取的最快方法是什么 127 0 0 1 到等效的整数表示 2130706433 相应地 反转所述操作的最快方法是什么 从整数开始2130706433到字符串表示形式 127 0
  • Java按日期升序对列表对象进行排序[重复]

    这个问题在这里已经有答案了 我想按一个参数对对象列表进行排序 其日期格式为 YYYY MM DD HH mm 按升序排列 我找不到正确的解决方案 在 python 中使用 lambda 很容易对其进行排序 但在 Java 中我遇到了问题 f
  • 在两个活动之间传输数据[重复]

    这个问题在这里已经有答案了 我正在尝试在两个不同的活动之间发送和接收数据 我在这个网站上看到了一些其他问题 但没有任何问题涉及保留头等舱的状态 例如 如果我想从 A 类发送一个整数 X 到 B 类 然后对整数 X 进行一些操作 然后将其发送
  • getResourceAsStream() 可以找到 jar 文件之外的文件吗?

    我正在开发一个应用程序 该应用程序使用一个加载配置文件的库 InputStream in getClass getResourceAsStream resource 然后我的应用程序打包在一个 jar文件 如果resource是在里面 ja
  • AWS 无法从 START_OBJECT 中反序列化 java.lang.String 实例

    我创建了一个 Lambda 函数 我想在 API 网关的帮助下通过 URL 访问它 我已经把一切都设置好了 我还创建了一个application jsonAPI Gateway 中的正文映射模板如下所示 input input params
  • 无法捆绑适用于 Mac 的 Java 应用程序 1.8

    我正在尝试将我的 Java 应用程序导出到 Mac 该应用程序基于编译器合规级别 1 7 我尝试了不同的方法来捆绑应用程序 1 日食 我可以用来在 Eclipse 上导出的最新 JVM 版本是 1 6 2 马文 看来Maven上也存在同样的
  • 获取 JVM 上所有引导类的列表?

    有一种方法叫做findBootstrapClass对于一个类加载器 如果它是引导的 则返回一个类 有没有办法找到类已经加载了 您可以尝试首先通过例如获取引导类加载器呼叫 ClassLoader bootstrapLoader ClassLo
  • JGit 检查分支是否已签出

    我正在使用 JGit 开发一个项目 我设法删除了一个分支 但我还想检查该分支是否已签出 我发现了一个变量CheckoutCommand但它是私有的 private boolean isCheckoutIndex return startCo
  • 使用 xpath 和 vtd-xml 以字符串形式获取元素的子节点和文本

    这是我的 XML 的一部分

随机推荐

  • 基于Qt的OpenGL编程(3.x以上GLSL可编程管线版)---(十九)混合

    Vries的教程是我看过的最好的可编程管线OpenGL教程 没有之一 其原地址如下 https learnopengl cn github io 04 20Advanced 20OpenGL 03 20Blending 关于混合的详细知识了
  • WOW装备大全(07.11.30)

    德需求 布拉克希斯的睡眠法杖 装备后绑定双手法杖131 223 伤害速度 3 每秒伤害 59 550 点护甲 39 耐力 耐久度 100 100 需要等级 64 装备 在猎豹 熊 巨熊和枭兽形态下的攻击强度提高234点 大地守卫者拾取后绑定
  • MySQL数据库学习笔记(九)实验课六之触发器和存储过程

    没想到这就是最后一次实验了 一点知识 道具 delimiter DELIMITER 这是用于指定语句分隔符的特殊命令 默认情况下 MySQL使用分号 作为语句的结束符 然而 当我们需要定义存储过程 触发器或函数等包含多条SQL语句的对象时
  • 单片机毕设 基于单片机的酒精浓度检测仪 - stm32 酒驾检测 酒精检测

    文章目录 0 简介 1 项目简介 2 系统设计 3 硬件设计 3 1 MQ 3 模块 3 2 GPRS模块 4 软件设计 4 1 GPRS模块使用 常用AT指令 4 1 1 数据收发demo 5 实现效果 5 最后 0 简介 Hi 大家好
  • 冷启动与热启动的定义

    在 Android 应用程序开发中 启动应用程序时 系统可以采用两种启动方式 冷启动和热启动 冷启动 Cold start 当应用程序从未启动过或者被系统杀死后再次启动时 就是冷启动 在冷启动时 应用程序的进程会被系统创建 应用程序需要重新
  • 100天精通Python(基础篇)——第9天:字符串拼接

    文章目录 拼接符号 代码示例 拼接符号 代码示例 print LCL 全世界 最帅 最有钱的 name lcl address 特斯拉总经理办公室 tel 8888888 print 我是 name 地址 address 电话 tel
  • 附录:kafka源码启动

    本文以源码2 8为例 准备如下 idea 2019 1 4 jdk 1 8 scala 2 12 8 gradle 6 8 1 zookeeper 3 4 10 kafka2 8源码 注意 以下安装都需要装在没有空格的路径上 比如D Pro
  • 分享一个selenium jar包 的下载地址,各版本都有,包括selenium-server-standalone.jar、selenium、selenium-server

    http selenium release storage googleapis com index html
  • 不懂代码也不用怕!10款无代码网站搭建平台

    作为设计师 对网站满脑子的构思 却受限于时间和技能 比如写代码 这是何其无奈 那个在你脑中盘桓许久的网站 或许是一个博客 可能是作品展示网站 但无论是哪种 想要让想法落地成形终究是一个艰巨的任务 今天为你推荐10款网站设计 开发工具能帮你改
  • Micropython驱动ST7735显示中文(中文字体库)

    大家是不是遇到显示中文就头大了 又是取模又是怎么的 但麻烦 太繁琐了 对确定的字符显示来说还可以 但不确定的内容时就麻烦了 所以 今天还是来讲讲干货了 来使用一个方便的方式来显示中文 不用取模 直接显示你想要的中英文字体 开始之前要说一下的
  • 戴尔服务器c系列,主打云计算市场 戴尔C系列服务器大盘点

    戴尔机架 R系列 塔式 T系列 和刀片 M系列 中采用至强5600处理器的服务器 其实 还有一个系列同样采用至强5600的处理器 它就是PowerEdge C 系列 这支系列是戴尔在2010年4月推出 是面向云计算平台的全新产品线 值得关注
  • 10种进阶方法让你快速测试端口连通性

    转载连接 介绍 Ping是Windows Linux和Unix系统下的一个检查网络连通性的命令工具 对于大部分互联网用户来说很实用 很方便 但是ping有个缺点 不能指定端口 如果源地址被设置禁ping 那么ping命令就形同虚设 为了弥补
  • Mysql教程(二):DDL学习

    Mysql教程 二 DDL学习 DDL Data Definition Language 数据定义语言 用来定义数据库对象 数据库 表 字段 1 DDL数据库操作 查询 查询所有数据库 SHOW DATABASES 查询当前数据库 SELE
  • 【华为OD】华为性格测试(综合测试)高分策略

    性格测试 综合测试 注意 1 性格测试非常重要 是一次否决制 18 个月有效期 所以态度一定要认真对待 不要随便乱选 2 做题原则 正向原则 积极乐观向上 3 时间为 25 30 分钟 会频繁出现重复选项重复出现的题目注意一致性 提示 1
  • 排列数组使得偶数在奇数的前面

    Name ReorderOddEven c Author 齐保元 Version Copyright Your copyright notice Description Hello World in C Ansi style include
  • 对js运算符“

    首先出个题 如图 假设对成长速度显示规定如下 成长速度为5显示1个箭头 成长速度为10显示2个箭头 成长速度为12显示3个箭头 成长速度为15显示4个箭头 其他都显示都显示0各箭头 用代码怎么实现 差一点的if else Js代码 var
  • 100天精通Python(基础篇)——第6天:标识符

    规则1 内容限定 限定只能使用 中文 英文 数字 下划线 注 不能以数字开头 规则2 大小写敏感 可以区分大小写 规则3 不可使用关键字 for while return等
  • (简单成功详细)CentOS 安装 node.js

    个人感觉比较好用的方法 目录 方法一 方法二 安装指定版本的nodejs并配置环境变量全局模块方法 方法一 1 安装yum sudo yum install epel release 2 安装nodejs sudo yum install
  • 我的2017年度技术回顾

    我为之前浪费的大把光阴后悔不已 如今正奋起直追 不知 为时可晚 较早是从事传统软件开发 主要以交付项目为主 后来慢慢转向互联网 属先知后觉那一类 一直从事Java软件研发管理工作 时下热门的小程序 大数据 人工智能 机器学习等接触很少 一方
  • volatile保证可见性,原理是什么

    VOLATILE 只保证可见性 Java多线程内存可见性 并不保证原子性 可见性 一个线程对共享变量的修改 更够及时的被其他线程看到 原子性 即不可再分了 不能分为多步操作 比如赋值或者return 比如 a 1 和 return a 这样