Java内存模型

2023-11-13

        Android开发中,存在大量并发的情况,因此也会遇到很多线程安全问题,在查询线程安全相关资料时,通常会查到Java内存模型的知识点。Java内存模型的主要目标是定义程序中各个变量的访问规则,即在虚拟机中将变量存储到内存和从内存中取出变量这样的底层细节。为了获得较好的执行效能,Java内存模型并没有限制执行引擎使用处理器的特定寄存器或缓存来和主内存进行交互,也没有限制即时编译器调整代码执行顺序这类权利。

        Java内存模型规定了所有的变量都存储在主内存中。每条线程有自己的工作内存,工作内存中保存了一份用到的变量,该变量是主内存变量的副本,线程对变量的所有操作(读取、赋值等)都必须在工作内存中进行,不能直接读写主内存中的变量。

        线程、工作内存、主内存三者交互关系如图:

        主内存与工作内存之间具体的交互协议,即一个变量如何从主内存拷贝到工作内存、如何从工作内存同步回主内存之类的实现细节,Java内存模型中定义了以下八种操作来完成:

  • lock(锁定):作用于主内存的变量,它把一个变量标识为一条线程独占的状态。
  • unlock(解锁):作用于主内存的变量,它把一个处于锁定状态的变量释放出来,释放后的变量才可以被其他线程锁定。
  • read(读取):作用于主内存的变量,它把一个变量的值从主内存传输到线程的工作内存中,以便随后load动作使用。
  • load(载入):作用于工作内存的变量,它把read操作从主内存中得到的变量值放入工作内存的变量副本中。
  • use(使用):作用于工作内存的变量,它把工作内存中变量的值传递给执行引擎,每当虚拟机遇到一个需要使用变量的值的字节码指令时将会执行这个操作。
  • assign(赋值):作用于工作内存的变量,它把一个从执行引擎接收到的值赋值给工作内存变量,每当虚拟机遇到一个给变量赋值的字节码指令时执行这个操作。
  • store(存储):作用于工作内存的变量,它把工作内存中一个变量的值传送到主内存中,以便随后的write操作使用。
  • write(写入):作用于主内存的变量,它把store操作从工作内存中得到的变量的值放入主内存的变量中。

        如果要把一个变量从主内存复制到工作内存,那就要按顺序地执行read和load操作,如果要把变量从工作内存同步回主内存,就要按顺序地执行store和write操作。注意,Java内存模型只要求上述两个操作必须按顺序执行,而没有保证必须是连续执行。也就是说read与load之间、store与write之间是可插入其他指令的,如对主内存中的变量a、b进行访问时,一种可能出现的顺序是read a、read b、load b、load a。除此之外,Java内存模型还规定了在执行上述八种基本操作时必须满足如下规则:

  • 不允许read和load、store和write操作之一单独出现,即不允许一个变量从主内存读取了但工作内存不接受,或者从工作内存发起回写了但主内存不接受的情况出现。
  • 不允许一个线程丢弃它最近的assign操作,即变量在工作内存中改变了之后必须把该变化同步回主内存。
  • 不允许一个线程无原因地(没有发生过任何assign操作)把数据从线程的工作内存同步回主内存中。
  • 一个新的变量只能在主内存中“诞生”,不允许在工作内存中直接使用一个未被初始化(load或assign)的变量,换句话说就是对一个变量实施use和store操作之前,必须先执行过了assign和load操作。
  • 一个变量在同一个时刻只允许一条线程对其进行lock操作,但lock操作可以被同一条线程重复执行多次,多次lock后,只有执行相同次数的unlock操作,变量才会被解锁。
  • 如果对一个变量执行lock操作,将会清空工作内存中此变量的值,在执行引擎使用这个变量前,需要重新执行load或assign操作初始化变量的值。
  • 如果一个变量事先没有被lock操作锁定,则不允许对它执行unlock操作,也不允许去unlock一个被其他线程锁定住的变量。
  • 对一个变量执行unlock操作之前,必须先把此变量同步回主内存中(执行store和write操作)。

        上述内存模型跟物理计算机对并发处理有很大的相似,由于计算机的CPU运算速度跟存储设备差距太大,所有加入了一层读写速度尽可能接近处理器运算速度的高速缓存来作为内存与处理器之间的缓冲:将运算需要使用到的数据复制到缓存中,让运算能快速进行,运算结束后再从缓存同步回内存中,这样处理器就无须等待缓慢的内存读写了。

        高速缓存的存储交互很好解决了处理器与内存的速度矛盾,但也引入新的问题:缓存一致性。在多处理系统中,每个处理器都有自己的高速缓存,但它们又共享同一个主内存。当多个处理器运算任务都涉及同一块主内存区域时,可能导致各自缓存数据不一致的情况。所有各个处理器访问缓存时都遵循一些协议(缓存一致性协议)。

        除此之外,为了使处理器内部运算单元能被充分利用,处理器可能会对输入代码进行乱序执行优化,在计算之后将乱序执行的结果重组,保证结果与顺序执行的结果一致。Java虚拟机的即时编译器中也有类似指令重排序优化。

参考:《深入理解Java虚拟机:JVM高级特性与最佳实践》

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java内存模型 的相关文章

  • 从队列更新活动的最佳方法

    我有一个LinkedBlockingQueue在我的 生产者 调解者 消费者 模型中的调解者中 Producer 首先更新将 Mediator 添加到 ActivityQueue 中 接下来 消费者 活动在队列中等待 侦听并获取下一个项目
  • 删除视图并重新创建它

    有没有办法删除设置的视图 setContentView R layout set map center mapView MapView findViewById R id mapview 如果我再次调用此视图 则会收到一条错误消息 java
  • Mesibo 通话 UI 未更新

    我正在尝试更改 Mesibo Call UI 的配置 但它并没有改变 我尝试如下 MesiboCallConfig mesiboCallConfig new MesiboCallConfig mesiboCallConfig backgro
  • Android-全屏视频视图

    我正在尝试使此 VideoView 以全屏模式显示 public class ViewVideo extends Activity private String filename private static final int INSER
  • Android相当于javascript的setTimeout和clearTimeout?

    setTimeout 有一个答案https stackoverflow com a 18381353 433570 https stackoverflow com a 18381353 433570 它没有提供我们是否可以像在 JavaSc
  • Android:拍照后调用裁剪活动

    我在解析拍摄照片的 uri 来裁剪活动时遇到问题 在我的应用程序中 用户可以拍摄一张照片或从图库中选择一张照片 然后裁剪并上传 一切听起来都很简单 从图库中选择时 图库应用程序会返回所选照片的 uri 如下所示 content media
  • 无法找到/下载 AppCompat-v7:23.1.1

    怎么了 我遇到了很多 找不到 appcompat v7 23 1 1 的问题 许多解决方案都不起作用 经过几个小时的思考和寻找答案 我遇到了一个奇怪的问题 I have gotAndroid 支持库 23 1 1 已安装 所有功能 exce
  • 有没有办法替代Android中的标准Log?

    有没有办法以某种方式拦截对 android 中标准 Log 的调用并执行其他操作 在桌面 Java 中 人们通常会得到一些记录器 因此有多种方法可以安装不同的日志处理程序 实现 但是 Android似乎对Log有静态调用 我找不到任何有关替
  • 如何在我的 Android 应用程序中实现应用内购买?

    如何在我的 Android 应用程序中实现应用内购买 我提到 http developer android com guide market billing billing integrate html billing service ht
  • 调试 Java InterruptedException,即查找原因

    在调试Android应用程序时 有时中断异常发生并使应用程序崩溃 我已经能够在默认异常处理程序上设置断点 但调用堆栈不提供信息 at java util concurrent locks AbstractQueuedSynchronizer
  • 无论如何,要控制宋何时选择Android.bp,何时不选择?

    使用新的构建系统 即 Soong 安卓取代Android mk with Android bp 还有 Android Q 及以上版本 Soong将选择所有Android bp文件 无论所有文件都存在于何处 早些时候 对于 2 级和 3 级模
  • 如何找到特定路线上两点之间的距离?

    我正在为我的大学开发一个 Android 应用程序 可以帮助学生跟踪大学巴士的当前位置 并为他们提供巴士到达他们的预计时间 截至目前 我获取了公交车的当前位置 通过公交车上的设备 和学生的位置 我陷入了必须找到两个 GPS 坐标之间的距离的
  • 从 Handler.obtainMessage() 获取什么参数

    我正在使用线程来执行一些 BT 任务 我正在尝试向 UI 线程发送消息 以便我可以基于我的 BT 线程执行 UI 工作 为此 我使用处理程序 但我不知道如何检索发送到处理程序的数据 要发送数据 我使用 handler obtainMessa
  • 以编程方式应用样式资源

    我没有找到一种以编程方式做到这一点的方法 所以我在这里发布这个问题 我也没有找到与此相关的任何问题 我有一个资源样式 在 res values styles xml 中定义 我想做的是使用 java 将这种样式应用到我正在操作的 View
  • Android - 正确使用 invalidateOptionsMenu()

    我一直在寻找很多invalidateOptionsMenu 我知道它的作用 但我想不出这种方法在现实生活中有用的任何例子 我的意思是 例如 假设我们要添加一个新的MenuItem to our ActionBar 我们可以简单地获取菜单on
  • 在尝试使用 GPS 之前如何检查 GPS 是否已启用

    我有以下代码 但效果不好 因为有时 GPS 需要很长时间 我该如何执行以下操作 检查GPS是否启用 如果启用了 GPS 请使用 GPS 否则请使用网络提供商 如果 GPS 时间超过 30 秒 请使用网络 我可以使用时间或 Thread sl
  • 使用 cordova cli 构建时的 Android 安装位置

    我正在使用 cordova CLI 工具构建一个大型 cordova phonegap 应用程序 我需要 AndroidManifest xml 文件中的 installLocation 具有 installLocation auto 或p
  • InAppMessage 一旦显示就会自动消失

    您好 我最近将 InAppMessaging 添加到我的项目中 这似乎很容易集成 但对我来说并没有按预期工作 首先 我将其添加到 build gradle 中 implementation com google firebase fireb
  • 如何在 Android 中保存 Edittext 中的文本而不丢失文本的粗体、斜体等功能

    我想做的就是从 Edittext 中获取文本 该文本具有粗体和斜体等功能 并将其保存在文本文件中 但是当我读回并显示它时 这些功能丢失了 它们不显示 如何通过将文本保存在文本文件或任何文件中来保持丰富的功能 您可以使用Html toHtml
  • Android BLE 扫描永远找不到设备

    几天以来 我尝试在我的应用程序中实现 BLE 连接 我知道我尝试连接的设备功能齐全 因此问题一定是我的代码 我用BluetoothLeScanner startScan 方法 但回调方法永远不会被调用 public void startSc

随机推荐

  • 解决若依后台管理系统打包线上偶发性elementUI的icon会出现乱码的问题

    1 问题图片 本地运行环境下是没有问题的 打包线上环境就会出现乱码情况 这时候我们发会发现在浏览器上看样式content 乱码 百度了很多 也尝试了各种方法都没有用 最后看到这篇博文添加链接描述得以解决 2 解决方法 升级sass版本至1
  • Vue中的生命周期

    什么是生命周期 生命周期 1 又名 生命周期回调函数 生命周期函数 生命周期钩子 2 是什么 Vue在关键时刻帮我们调用的一些特殊名称的函数 3 生命周期函数的名字不可更改 但函数的具体内容是程序员根据需求编写的 4 生命周期函数中的thi
  • Java的序列化

    写在前面 本文看下序列化和反序列化相关的内容 源码 1 为什么 什么是序列化和反序列化 Java对象是在jvm的堆中的 而堆其实就是一块内存 如果jvm重启数据将会丢失 当我们希望jvm重启也不要丢失某些对象 或者是需要将某些对象传递到其他
  • SQL8 查找某个年龄段的用户信息

    描述 题目 现在运营想要针对20岁及以上且23岁及以下的用户开展分析 请你取出满足条件的设备ID 性别 年龄 用户信息表 user profile id device id gender age university province 1
  • 前端UI组件库深度解析:构建现代化的用户体验

    引言 在当今的前端开发中 UI组件库已经成为了我们工具箱中不可或缺的一部分 这些库可以极大地提高我们的工作效率 同时也使我们能够专注于实现真正的业务逻辑 而不是重复地编写UI代码 本篇博客将详细地探讨UI组件库的核心概念 特性以及如何有效地
  • Stm32旧版库函数8——stm32 PWM波 TIM4 PB6 PB7 PB8 PB9

    include
  • html发布页,发布页入口.html

    发布页入口 axure utils getTransparentGifPath function return resources images transparent gif axure utils getOtherPath functi
  • C++11 类型推导decltype(一)

    我们之前使用的typeid运算符来查询一个变量的类型 这种类型查询在运行时进行 RTTI机制为每一个类型产生一个type info类型的数据 而typeid查询返回的变量相应type info数据 通过name成员函数返回类型的名称 同时在
  • Transformer详细解读与预测实例记录

    文章目录 Transformer详细解读与预测实例记录 1 位置编码 1 输入部分 2 位置编码部分 2 多头注意力机制 1 基本注意力机制 2 transformer中的注意力 3 残差和LayerNorm 1 残差 2 LayerNor
  • 错误Unexpected token × in JSON at position 3的解决

    Uncaught SyntaxError Unexpected token in JSON at position 3 at JSON parse
  • Tableau常用函数

    1 ABS number 返回给定数字的绝对值 ABS 7 7 ABS 字段 字段中包含的所有数字的绝对值 2 ATTR expression 如果它的所有行都有一个值 则返回该表达式的值 否则返回星号 会忽略 Null 值 其实维度也可以
  • JAVA_常用API-Math

    目录 前言 一 Math类 Max类的常用方法 例题 1 取绝对值 返回正数 输出结果为 2 向上或者向下取整 3 求指数次方 以及四舍五入 4 生成随机数random 范围是 0 0 1 0 0 0 1 0 总结 前言 本篇文章作为作者学
  • 我们人类与人工智能技术究竟是怎样的关系?

    图片来自pixabay com 来源 赛先生 撰文 爱德华 阿什福德 李 加州大学伯克利分校教授 责编 李珊珊 摘要 数字技术正在和人类文明协同进化 我们依赖技术而生存 技术也依赖我们 这种合作共生的趋势越来越明显 技术并不是所谓的 应用科
  • 解决:java -version,java,javac不是内部或外部命令,也不是可运行的程序 或批处理文件。

    命令行输入java java version javac都显示不是内部或外部命令 1 首先查看了自己的环境变量 经过学习确实都是环境变量出现问题 之前的环境变量都是 JAVA HOME bin 全部换成了绝对路径如 C Program Fi
  • 弃用http改用https的缘故,与密钥的使用,证书意义

    为何弃用http协议 在十几年前 我们的传输协议是http协议 为何到了如今改成了https协议呢 为了安全的考虑 在http协议中 我们的内容是透明的 不被保护的 在黑客等恶意分子的面前 信息极其任意被破译 让我们看看客户端如果使用htt
  • spring笔记1(基础(IoC控制反转、DI依赖注入)、整合Junit、整合web)

    目录 前言 1 spring框架概述 1 什么是spring 1 2 spring由来 1 3spring核心 1 4spring优点 1 5 spring体系结构 2入门案例 IoC 掌握 2 1 导入jar包 2 2 目标类 2 3 配
  • R中关于金融的包

    quantmod 数据和图形 TTR 技术分析 blooter 账户管理 FinancialInstrument 金融产品 quantstrast 策略模型 PerformanceAnalytics 表现分析 这些R包依然在发展中 有些还被
  • 原生js导出excel,并保留样式

    前端表格导出excel一般我们使用xlsx等插件导出 但如果想保留表格的样式导出的话 还需要再使用其他的插件才行 如要保留宽度 字体颜色 背景颜色等样式 这里可以直接使用简短的 原生js方法即可导出带样式的excel文件 直接上代码 原生表
  • 股票实时数据接口

    From http chenpeng info html 1058 做了一点股票分析数据准备 做了个均线图 http stock chenpeng info randomone 查询股票走势请移步 http stock chenpeng i
  • Java内存模型

    Android开发中 存在大量并发的情况 因此也会遇到很多线程安全问题 在查询线程安全相关资料时 通常会查到Java内存模型的知识点 Java内存模型的主要目标是定义程序中各个变量的访问规则 即在虚拟机中将变量存储到内存和从内存中取出变量这