Java 最终字段值的“最新”保证是否扩展到间接引用?

2023-11-22

Java 语言规范定义了 Final 字段的语义第17.5节:

Final 字段的使用模型很简单。在对象的构造函数中设置该对象的最终字段。在对象的构造函数完成之前,请勿将对正在构造的对象的引用写入其他线程可以看到的位置。如果遵循这一点,那么当另一个线程看到该对象时,该线程将始终看到该对象的最终字段的正确构造版本。它还将看到这些最终字段引用的任何对象或数组的版本,这些版本至少与最终字段一样最新。

我的问题是 - “最新”保证是否扩展到嵌套数组和嵌套对象的内容?

简而言之:如果一个线程将可变对象图分配给对象中的最终字段,并且该对象图从未更新,那么所有线程是否可以通过最终字段安全地读取该对象图?

一个示例场景:

  1. 线程 A 构造 ArrayLists 的 HashMap,然后将 HashMap 分配给类“MyClass”实例中的最终字段“myFinal”
  2. 线程 B 看到对 MyClass 实例的(非同步)引用并读取“myFinal”,然后访问并读取 ArrayList 之一的内容

在这种情况下,线程 B 所看到的 ArrayList 成员是否保证至少与 MyClass 的构造函数完成时一样最新?

我正在寻求 Java 内存模型和语言规范的语义澄清,而不是同步等替代解决方案。我梦想的答案是肯定或否定,并参考相关文本。

更新:

  • 我对 Java 1.5 及更高版本的语义感兴趣,即通过 JSR 133 引入的更新的 Java 内存模型。此更新中引入了对 Final 字段的“最新”保证。

在这种情况下,成员是 线程 B 看到的 ArrayList 保证至少达到 日期与 MyClass 时一样 构造函数完成了吗?

是的,他们是。

当线程第一次遇到引用时,需要读取内存。因为构建了哈希映射,其中的所有条目都是全新的,那么对对象的引用就是up-to-date到构造函数完成时的状态。

初次相遇后,通常的可见性规则将适用。因此,当其他线程更改最终引用中的非最终字段时,其他线程可能看不到该更改,但它仍然会看到来自构造函数的引用。

实际上,这意味着如果您不在构造函数之后修改最终的哈希映射,则其内容对于所有线程都是常量。

EDIT

我知道我以前在某处见过这个保证。

这是一段有趣的内容article描述 JSR 133

初始化安全

新的 JMM 还力求提供 初始化安全的新保证 ——只要一个对象被正确构造(意味着一个 对对象的引用不是 在构造函数之前发布 完成),然后所有线程都会看到 其最终字段的值 在其构造函数中设置, 无论是否 同步用于传递 从一个线程到另一个线程的引用。 此外,任何变量都可以 通过最后一个字段达到 正确构造的对象,例如 a 引用的对象的字段 最后的字段,也保证是 对其他线程也可见。这 意味着如果最终字段包含 引用,比如说,一个 LinkedList, 除了正确的值 引用对其他人可见 线程,还有该线程的内容 LinkedList 在构造时会 对其他线程可见,无需 同步。结果是 显着加强 Final 的含义——final 字段 可以安全地访问,无需 同步,并且编译器 可以假设最终字段不会 改变,因此可以优化 多次获取。

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

Java 最终字段值的“最新”保证是否扩展到间接引用? 的相关文章

  • 策略模式还是命令模式?

    假设我有一个金融交易列表 我需要针对这些交易执行一系列验证规则 一个例子是我有一笔购买产品的交易 但是首先我需要验证交易中的帐户是否有足够的可用资金 产品没有售完等 由于这些规则 交易将是标记为拒绝 并应指定错误代码 当然 我正在考虑用一个
  • 使类只能从特定类实例化

    假设我有 3 节课class1 class2 and class3 我怎样才能拥有它class1只能通过实例化class2 class1 object new class1 但不是 class3 或任何其他类 我认为它应该与修饰符一起使用
  • 如何作为应用程序发布到页面?

    所以 我有一个应用程序 Facebook 应用程序实体 并且我有一个页面 我想使用应用程序通过java代码 通过restfb或任何其他建议 发布到页面 看起来我错过了页面授予应用程序发布权限的阶段 不知道该怎么做 谢谢你们 乌里 您只能 作
  • 重写 getPreferredSize() 会破坏 LSP

    我总是在这个压倒一切的网站上看到建议getPreferredSize 而不是使用setPreferredSize 例如 如前面的线程所示 对于固定大小的组件 使用重写 getPreferredSize 而不是使用 setPreferredS
  • 迭代函数可以调用自身吗?

    当观看下面的 MIT 6 001 课程视频时 讲师在 28 00 将此算法标记为迭代 但是 在 30 27 他说这个算法和实际的 递归 算法都是递归的 该函数正在使用基本情况调用自身 那么这次迭代情况如何 private int itera
  • Android 性能:SharedPreferences 的成本

    当我的应用程序启动时 我使用分片首选项中的值填充容器类 这个想法是处理 SharedPreferences 和 PreferenceManager 一次 因为我猜它们很重 这是一个示例 SharedPreferences prefs Pre
  • 在哪里保存选项值、重要文件的路径等[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我正在创建一个程序 需要设置一些选项值以及图像文件的一些路径 SQLite 数据库的路径 有关各种按钮上文本的一些信息 有关要使用哪个数据库的信
  • 我需要在 JFileChooser(打开模式)中显示不带扩展名的文件名。如何?

    我在打开模式下使用 JFileChooser 我需要显示不带扩展名的 文件名 字段 如何 我知道文件视图 它删除文件系统文件中的扩展名 但将所选文件中的扩展名保留在 文件名 字段中解释 http saveimg ru show image
  • JUnit5 平台启动器 API - 如果没有至少一个测试引擎,则无法创建启动器

    我正在尝试升级我们的自动化测试套件的测试能力以接受 JUnit5 测试并遵循JUnit 平台启动器 API 说明 https junit org junit5 docs current user guide launcher api我收到错
  • 这个等待通知线程语义的真正目的是什么?

    我刚刚遇到一些代码 它使用等待通知构造通过其其他成员方法与类中定义的线程进行通信 有趣的是 获取锁后 同步范围内的所有线程都会在同一锁上进行定时等待 请参见下面的代码片段 随后 在非同步作用域中 线程执行其关键函数 即 做一些有用的事情1
  • 如何在 JPA 和 Hibernate 中将数据库生成的列值定义为只读字段?

    使用 MariaDB 10 2 可以定义日期时间的默认值 例如创建和最后修改 我应该如何将此列作为只读字段访问 因为这个值应该只在数据库的控制之下 并且不应该从代码中修改 但我想在代码中读取这个属性 这很简单 只需设置insertable
  • 正确签名的 JNLP 应用程序无法在 Java 7 中运行

    我有一个 JNLP 应用程序 由于证书过期需要更新 我有一个经过 CA 验证的新证书 我已将新证书导入到我的密钥库中 我已导入完整的证书链 我的构建文件对构建中的 jar 进行签名和时间戳
  • 拆分/标记化/扫描字符串并注意引号

    Java中是否有默认 简单的方法来分割字符串 但要注意引号或其他符号 例如 给定以下文本 There s a man that live next door in my neighborhood and he gets me down Ob
  • 在 Java 中创建 XML 文件的最佳方法是什么?

    我们目前使用 dom4j 来创建 XML 文件 不过 我猜现在有更好的东西了 如果我们使用的是 Java 1 6 或更高版本 那么在编写 XML 文件时最好使用什么类 运行速度最快 使用简单 我不需要构建一个 DOM 然后编写整个 DOM
  • 使用单独的线程在java中读取和写入文件

    我创建了两个线程并修改了 run 函数 以便一个线程读取一行 另一个线程将同一行写入新文件 这种情况会发生直到整个文件被复制为止 我遇到的问题是 即使我使用变量来控制线程一一执行 但线程的执行仍然不均匀 即一个线程执行多次 然后控制权转移
  • 使用 PC/SC 读卡器验证 Ultralight EV1

    我在尝试使用 Java 中的 PC SC 读卡器 特别是 ACR1222L 验证 Ultralight EV1 卡时遇到问题 我能够使用 ISO 14443 3 标签的相应 APDU 在不受保护的标签上进行写入和读取 但是 我找不到运行 P
  • 让 Hibernate 和 SQL Server 与 VARCHAR 和 NVARCHAR 良好配合

    我目前正在大型数据库的某些表中启用 UTF 8 字符 这些表已经是 MS SQL 类型 NVARCHAR 此外 我还有几个使用 VARCHAR 的字段 Hibernate 与 JDBC 驱动程序的交互存在一个众所周知的问题 例如 参见在 h
  • 受信任的 1.5 小程序可以执行系统命令吗?

    如果是的话 这个能力有什么限制吗 具体来说 我需要以 Mac OSX 为目标 我以前用过这个在 Windows 系统上启动东西 但从未在 Mac 上尝试过 public void launchScript String args Strin
  • 如何使用自定义 JDK 构建 Jenkins 项目?

    我有一个常规的 Jenkins 实例 运行一些多分支管道 该实例在 JDK 11 上运行 因为 Jenkins 并不真正支持更高版本 没关系 但不好的是 我的所有管道似乎也都受到 Java 11 的限制 Jenkins 仅使用它自己也使用的
  • mybatis:使用带有 XML 配置的映射器接口作为全局参数

    我喜欢使用 XML 表示法来指定全局参数 例如连接字符串 我也喜欢 Mapper 注释 当我尝试将两者结合起来时 我得到这个例外 https stackoverflow com questions 4263832 type interfac

随机推荐

  • 如何在Windows 7中设置应用程序的任务栏图标

    如何在 PyQt4 中设置应用程序的任务栏图标 我尝试过setWindowIcon 它成功地将图标设置在主窗口的左上角 但它不会影响Windows 7任务栏中显示的图标 任务栏图标仍然是默认的Python pyw图标 这是我的代码 from
  • __POSIX_VISIBLE 正在破坏我在 cygwin 上的 pthreading

    我正在编译一个在 cygwin 上使用 pthreads 和 gcc 确切地说是 g 的项目 鉴于我一直在linux上开发这个 我从来没有遇到过任何问题 但现在 我无法编译使用某些 pthread 函数的代码 编译器抱怨这些函数未声明 我意
  • 如何在 Linux 上中断任意 TCP/IP 连接?

    是否有任何命令可用于中断某个程序的现有 TCP IP 连接 操作系统是否知道 TCP 连接中的任何内容 或者操作系统是否只看到本地套接字上的 TCP 传输 并且不知道哪个请求被发送到哪个套接字 例如 如果 Firefox 向某个服务器的端口
  • 如何创建具有两个键(键对、值)的 HashMap?

    我有一个二维整数数组 我希望将它们放入 HashMap 中 但我想根据数组索引访问 HashMap 中的元素 就像是 对于 A 2 5 map get 2 5 它返回与该键关联的值 但是如何创建带有一对键的 hashMap 呢 或者一般来说
  • 在 Linux 上使用 ncurses 时未定义的引用

    我正在尝试开始在 Linux 上使用 ncurses 开发程序 我什至无法编译 Hello World 示例 这是代码 include
  • Angular UI 中的 $dialog.messageBox() 在哪里?

    我找不到 dialogAngularUI 中的服务 我尝试探索一个简单的messageBox 使用以下命令创建确认对话框 modal 也找不到那个 有人可以建议我如何使用 AngularJS Angular UI 创建一个简单的对话框 比如
  • 在 Spring 3 中组织类以进行组件扫描的明智方法是什么?

    我已经开始使用 Spring 3 开发一个新项目 并且正在使用注释 我喜欢我可以连接我的类来注入依赖项 但我知道这是一个不好的做法context component scan从基础包开始 我正在使用一个DispatcherServlet它有
  • mysql变量中的字段名

    是否可以选择名称为字符串的字段 SELECT fieldname FROM table 我需要这个触发器才能具有动态字段名称 就像是 SET fieldname NEW name UPDATE table SET fieldname 1 如
  • 免费如何知道要免费多少?

    在 C 编程中 您可以将任何类型的指针作为参数传递给 free 它如何知道要释放的已分配内存的大小 每当我将指针传递给某个函数时 我还必须传递大小 即 10 个元素的数组需要接收 10 作为参数才能知道数组的大小 但我不必将大小传递给免费功
  • AngularJS 对跨源资源执行 OPTIONS HTTP 请求

    我正在尝试设置 AngularJS 与跨域资源进行通信 其中提供模板文件的资产主机位于不同的域中 因此 Angular 执行的 XHR 请求必须是跨域的 我已为 HTTP 请求添加了适当的 CORS 标头到我的服务器 以使其工作 但它似乎不
  • 为什么 Serverless 在尝试打包或部署时会产生无效的跨设备链接错误?

    运行任一命令时 sudo serverless package or sudo serverless deploy 我得到以下回溯 错误 错误 异常 回溯 最近一次调用 文件 var lang lib python3 6 shutil py
  • WCF,发布 JSON 化数据

    我有一个复杂的类型 DataContract public class CustomClass DataMember public string Foo get set DataMember public int Bar get set 然
  • 计算用于定义二次贝塞尔曲线分段的参数

    我有一条二次贝塞尔曲线 描述为 startX startY 到 anchorX anchorY 并使用控制点 controlX controlY 我有两个问题 1 我想根据 x 点确定该曲线上的 y 点 2 然后 给定贝塞尔曲线上的线段 由
  • 如何在 Django 模板中声明变量

    如何在 Django 1 8 模板中声明变量 例如 my var My String 这样我就可以像这样访问它 h1 trans my var h1 Edit 为了证明我的目的 这是我的代码 my var String Text block
  • 使用 SetParameters.xml 通过 powershell 将网站发布到 Azure

    是否有机会使用 SetParameters xml 文件在 Web 部署包中设置参数 我想通过 powershell 脚本和 cmdlet 部署应用程序 选择 Azure订阅 发布 AzureWebsiteProject 但我还没有找到如何
  • 在 Python 版本 3.10 上使用 pip3 在 M1 Mac 上安装 numpy 时出现“不兼容的架构(具有 'arm64',需要 'x86_64')”错误

    我试图使用 pip3 在 M1 Macbook 上安装 numpy 版本 1 22 3 pip3 表示该包存在 但是当我尝试导入该模块时 会向我抛出一个错误 提示我 Importing the numpy C extensions fail
  • 如何中途开始测量?

    在我的赞美诗中 我需要从中间开始第一小节 它的拍值是 3 4 但我必须插入两个空的 不显示的八分音符 我怎么做 我用过o4 o4 c8 d 下面是第一个措施 但 lilypond 不喜欢这样 正确的方法是什么 这是该行 o4 o4 c8 d
  • 使用 opencv 构建自定义 svm 内核矩阵

    我必须训练支持向量机模型 并且我想使用自定义内核矩阵 而不是预设的矩阵 如 RBF Poly 等 我怎样才能用opencv的机器学习库做到这一点 如果可能的话 谢谢你 AFAICT OpenCV 不直接支持 SVM 的自定义内核 看起来 L
  • 返回所有小于 M 的素数

    给定一个整数 M 返回所有小于 M 的素数 给出一个尽可能好的算法 需要考虑时间和空间复杂度 埃拉托斯特尼筛法是一个很好的起点 http en wikipedia org wiki Sieve of Eratosthenes
  • Java 最终字段值的“最新”保证是否扩展到间接引用?

    Java 语言规范定义了 Final 字段的语义第17 5节 Final 字段的使用模型很简单 在对象的构造函数中设置该对象的最终字段 在对象的构造函数完成之前 请勿将对正在构造的对象的引用写入其他线程可以看到的位置 如果遵循这一点 那么当