将对象重新放入 ConcurrentHashMap 是否会导致“发生在”内存关系?

2023-12-19

我正在与existing具有 ConcurrentHashMap 形式的对象存储的代码。映射内存储了可供多个线程使用的可变对象。根据设计,没有两个线程会尝试同时修改一个对象。我关心的是线程之间修改的可见性。

目前,对象的代码在“setter”上具有同步(由对象本身保护)。 “getter”上没有同步,成员也不是易失性的。对我来说,这意味着无法保证可见性。然而,当一个对象被修改时re-put回到地图(put()再次调用方法,相同的键)。这是否意味着当另一个线程将对象从映射中拉出时,它会看到修改?

我在 stackoverflow 上对此进行了研究,在JCIP http://jcip.net/,以及 java.util.concurrent 的包描述中。我认为我基本上让自己感到困惑......但导致我问这个问题的最后一根稻草来自包装说明,它指出:

将对象放入任何并发集合之前的线程中的操作发生在另一个线程中从集合中访问或删除该元素之后的操作之前。

关于我的问题,“操作”是否包括在 re-put() 之前对存储在地图中的对象进行的修改?如果所有这些确实导致跨线程的可见性,那么这是一种有效的方法吗?我对线程比较陌生,非常感谢您的评论。

Edit:

谢谢大家的回复!这是我在 StackOverflow 上的第一个问题,它对我很有帮助。

我必须和ptomli https://stackoverflow.com/users/134894/ptomli的答案,因为我认为它最清楚地解决了我的困惑。也就是说,在这种情况下,建立“发生之前”关系并不一定会影响修改可见性。关于我在文中描述的实际问题,我的“标题问题”的结构很差。ptomli https://stackoverflow.com/users/134894/ptomli现在的答案与我读到的内容一致JCIP http://jcip.net/:“为了确保所有线程都能看到共享可变变量的最新值,读取和写入线程必须在公共锁上同步”(第 37 页)。将对象重新放回到映射中不会为修改插入的对象的成员提供此公共锁。

我很欣赏所有关于改变的技巧(不可变的对象等),并且我完全同意。但对于这种情况,正如我提到的,由于仔细的线程处理,没有并发修改。一个线程修改一个对象,然后另一个线程读取该对象(CHM 是对象传送器)。我认为 CHM 不足以确保稍后执行的线程将看到我提供的情况下第一次执行的修改。然而,我认为你们很多人正确回答了标题问题.


你打电话concurrHashMap.put每次写入对象后。但是您没有指定您还调用concurrHashMap.get每次阅读之前。这是必要的。

所有形式的同步都是如此:您需要在两个线程中都有一些“检查点”。只同步一个线程是没有用的。

我还没有检查 ConcurrentHashMap 的源代码来确保put and get触发之前发生的事件,但它们应该这样做是合乎逻辑的。

但是,即使您同时使用,您的方法仍然存在问题put and get。当您修改一个对象并且该对象在它被修改之前被其他线程使用(处于不一致的状态)时,就会出现问题put。这是一个微妙的问题,因为您可能认为旧值会被读取,因为它还没有被读取。put但这不会造成问题。问题是,当您不同步时,不能保证获得一致的旧对象,而是行为未定义。 JVM 可以随时更新其他线程中对象的任何部分。仅当使用某些显式同步时,您才能确定在线程之间以一致的方式更新值。

你可以做什么:
(1) 同步代码中各处对象的所有访问(getter 和 setter)。请小心设置器:确保不能将对象设置为不一致的状态。例如,在设置名字和姓氏时,拥有两个同步设置器是不够的:您必须同时获取这两个操作的对象锁。
or
(2) 当你put地图中的对象,放置深层副本而不是对象本身。这样其他线程永远不会读取处于不一致状态的对象。

EDIT:
我刚刚注意到

目前对象的代码在“setters”上具有同步 (由对象本身保护)。上没有同步 “吸气剂”的成员也不是不稳定的。

不是很好。正如我上面所说,仅在一个线程上同步根本就不是同步。您可能会在所有编写器线程上同步,但谁在乎呢,因为读者不会获得正确的值。

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

将对象重新放入 ConcurrentHashMap 是否会导致“发生在”内存关系? 的相关文章

  • 将嵌套的 ArrayList 转换为 Java List

    我有这个方法 public List
  • 如何正确地将MapStruct与Eclipse集成? (包括Lombok java代理)

    我愿意在一些官方项目中使用MapStruct 所以我决定先对其进行一些测试 我需要让它与 eclipse 集成工作 并遵循 MapStruct 网站上提供的所有说明 但是 到目前为止还没有运气 有人成功实现了这种整合吗 如果是的话我可以缺少
  • 从插件设置 Maven 属性

    我在这里阅读了一些关于如何从 Maven 插件设置属性的问题 其中大多数讨论了应用程序的版本号 似乎没有简单的方法可以做到这一点 我发现的最佳解决方案是拥有一个从插件更新的 filter properties 文件 并由主 pom 文件使用
  • 确定列表编号是否连续

    我在 Java 工作 我有一个无序列表 包含 5 个数字 范围从 0 100 没有重复 我想检测其中 3 个数字是否连续且没有间隙 例子 9 12 13 11 10 true 17 1 2 3 5 true 19 22 23 27 55 f
  • 如何在异常处理程序中访问访问请求主体

    我们有一个 Spring Boot 应用程序 我们的控制器期望在我们的端点之一中有一个 XML 文档元素 PostMapping value api v1 do stuff consumes APPLICATION XML VALUE pr
  • JCombobox 字符串项(可见)和整数键(固有)

    我有一个数据库模式 它将作为 JTable 列显示在 JCombobox 中以选择名称 但我希望将 ID 字段插入 作为外键 到另一个表中 通常 在下拉列表中选择一个项目 将所选项目带到组合框的显示区域 我想要做的是 当选择组合框中的任何项
  • Java生成范围内不重复的随机数

    我想生成 1 到 4 范围内的随机数 包括 4 这是我的代码 int num r nextInt 4 1 r is instance of Random 但是 我在循环中运行上述代码 并且不想重复随机数 现在发生的事情我经常得到 1 1 1
  • Java OR 运算符优先级

    如何在 Java 中以 if 的方式链接条件语句b是假的 不如不检查c If a and c是假的 并且b是真的 确实c会被检查吗 if a b c 我正在寻找 PHP 所拥有的类似功能 但两者之间存在差异OR and 爪哇 如果左操作数是
  • Java Sound可以用来控制系统音量吗?

    Java 声音优惠FloatControl各种声音线路功能的实例 以及MASTER GAIN http docs oracle com javase 7 docs api javax sound sampled FloatControl T
  • Spring Security登录返回404

    我目前正在使用 Spring 框架开发我的博客 我正在实现 Spring Security 用于登录目的 一切都按预期进行 直到我提交始终返回 404 代码的登录凭据 这是我的 web xml 代码e
  • 膨胀类 android.support.v7.internal.widget.NativeActionModeAwareLayout 时出错

    如果您以前解决过这个问题 请有人帮助我 我正在尝试使用材料设计制作一些东西 以便应用程序可以运行到 API 10 的低版本 我的代码中没有任何错误 但我不断收到此错误 Android 日志猫 06 01 05 05 37 414 E And
  • 使用枚举变量切换字符串

    我有一个具有不同值的枚举 并且想要切换字符串变量 现在 我在尝试将枚举值转换为字符串 可以用作大小写常量 时遇到了困难 我最好的尝试是将枚举转换为字符串数组 但开关似乎不接受数组值作为大小写常量 IntelliJ 说 需要恒定的表达 Enu
  • 一起使用 String 和 int 时的 System.out.println 行为 [重复]

    这个问题在这里已经有答案了 考虑下面的代码片段 public class Student public static void main String args int a 3 int b 4 System out println a b
  • 使用 java 中的准备好的语句插入自定义 SQL 类型

    我有一些自定义类型 它们基本上都是枚举 以下是它们的外观示例 CREATE TYPE card suit AS ENUM spades clubs hearts diamonds 我在 Java 中有一些准备好的语句 看起来像这样 Setu
  • 如何告诉 Eclipse 忽略 Ant build.xml 中的错误?

    我有一个使用 Maven 构建的 Eclipse 项目 并且我在 Eclipse 中使用 m2eclipse 插件来获得 Maven 支持 然而这个项目还包含一个build xml它并不用于实际构建项目 而只是用于编写脚本功能 作为项目开发
  • 在大画布上滚动

    我需要一些帮助来了解滚动绘制到 Android 画布上的项目的基础知识 假设我想创建一个时间线 其中 0 处的时间是可视化的顶部 并且随着时间的增加 时间线继续呈现在上一个点下方 如果我想在 Android 上渲染它 我知道我可以通过重写
  • 有没有办法防止 Spring Boot 覆盖 bean?

    与春天的抽象可刷新应用程序上下文 http docs spring io spring docs current javadoc api org springframework context support AbstractRefresh
  • 无法验证 serde:org.openx.data.jsonserde.jsonserde

    我编写了这个查询来在配置单元上创建一个表 我的数据最初是 json 格式 所以我已经下载并构建了 serde 并添加了它运行所需的所有 jar 但我收到以下错误 FAILED Execution Error return code 1 fr
  • Java 8 流过滤器 - 基于排序的更新

    我正在尝试对过滤器中的字段进行排序 输入文件 样本记录 DocumentList Document id 5975ff00a213745b5e1a8ed9 u id mailboxcontent id 5975ff00a213745b5e1
  • E/libEGL: validate_display:99 错误 3008 (EGL_BAD_DISPLAY) API 24 或更高版本

    当我使用 API 为 24 或更高版本的设备时 我收到此错误 E libEGL validate display 99 错误 3008 EGL BAD DISPLAY XML 代码 activity main xml

随机推荐

  • 是否存在不应在 .pch 文件中添加所有导入的原因?

    我主要指的是应用程序级导入 而不是构建库时的导入 在这种情况下 很明显为什么应该避免导入 pch 文件内的标头 要点是 pch文件的优点是它可以预编译一次并且无需处理 如果您将所有应用程序标头导入 pch 每次更改其中任何一个标头时都必须重
  • 如何创建具有多个子行(嵌套表)的 jQuery 数据表?

    问题 我需要创建一个具有嵌套表格式的表 当用户单击加号按钮时 它应该显示嵌套表 如果他们点击减号按钮 它应该隐藏 我已经完成了jquery datatable 它工作正常 但我无法显示子表的多行 我已经尝试了很多次 但无法显示正确的格式 这
  • 如何在每个循环周期更新一步进度条? C#

    使用 C Windows 窗体创建 net 应用程序 如何在 100 个循环的每个循环中更新进度条 1 步 我正在循环中处理 Excel 工作表 进度条控件位于 UI 类中 该类连接到控制器类 该控制器类连接到自定义类 MVC 模式 循环位
  • XSLT:如何通过另一个节点查找该节点的值

    我不确定我是否正确地提出了这个问题 这就是为什么我在任何地方都找不到答案 但基本上我需要将一个节点与另一个节点进行匹配 并使用同级节点作为值 这是一个例子
  • Angular 6 中使用 Typescript 进行 Datalayer.push

    当我点击按钮时 我应该发送到数据层信息 但我不知道该怎么做 因为我使用的是 Angular 6 所以我需要使用 Typescript 和 window dataLayer push 不起作用 给我这个错误 Form
  • 如何检测 iOS 8 中 UITextField 上的删除键?

    我对 UITextField 进行了子类化 并实现了 UIKeyInput 协议的 deleteBackward 方法来检测按下的退格键 这在 iOS 7 上工作正常 但在 iOS 8 上不行 当我按退格键时 UITextField 上不再
  • 删除溢出的内联元素行之间的边距

    我正在创建一个基于图块的游戏 并使用块渲染来更新大量图块 我试图以最简单的方式做到这一点 所以我一直在尝试使用 HTML 的默认布局 现在我正在创建 内联块 省略元素之间的空白以避免它们之间的水平空间 但是当块溢出并创建新行时 会有一些垂直
  • 如何在 Swift 中更改 UIBezierPath 的颜色?

    我有一个实例UIBezierPath我想将描边的颜色更改为黑色以外的颜色 有谁知道如何在 Swift 中做到这一点 有了 Swift 5 UIColor has a setStroke https developer apple com d
  • 过滤 Chrome 控制台消息

    有没有办法在 Chrome 控制台中过滤消息 例如 我不想看到来自 包含 JQMIGRATE 的消息 您可以通过在前面添加来否定过滤器 例如 JQMIGRATE将排除包含字符串 JQMIGRATE 的消息 正则表达式过滤器也可以通过这种方式
  • 自动装配依赖项注入失败

    我在 Java EE 应用程序中使用 Spring 和 Hibernate 该项目托管于这个 GitHub 存储库 http github com whirlwin niths 我通过服务使用 Autowired 时遇到问题 如下所示 pa
  • Django 信号 - kwargs['update_fields'] 在通过 django admin 进行模型更新时始终为 None

    我的 django 应用程序中有一个信号 我想检查模型中的某个字段是否已更新 以便我可以继续执行某些操作 我的模型看起来像这样 class Product models Model name models CharField max len
  • Auth::attempt() 在 Laravel 5.5 中不起作用

    我的注册表单正在运行 它将用户存储到数据库 但是当用户登录时 Auth attempt 返回 false 这是我的登录代码 我将密码以 sha1 加密形式存储在 db 中 Route post login function creds ar
  • 将 Pip 包传输到 conda

    我目前正在使用一台共享的 Ubuntu 机器 其中有蟒蛇2 7以及通过安装的多个软件包pip python version Python 2 7 12 pip version pip 18 0 from usr local lib pyth
  • 验证十进制数

    我正在阅读一些 csv 文件 其中包含表示十进制数的字符串 我的麻烦是 很多时候我接收使用不同区域设置的文件写入 例如 file1 csv的price列的值为129 13 是小数点分隔符 file1 csv的price列值为129 13 为
  • 如何计算密码学中的对数?

    我正在尝试对字节执行非线性函数来实现 SAFER 该算法需要计算字节的以 45 为底的对数 我不明白如何做到这一点 log45 201 1 39316393 当我将其分配给一个字节时 该值被截断为 1 并且我无法恢复确切的结果 我该怎么处理
  • 为什么这段 Javascript 代码这么慢?

    我有这段 Javascript 代码 在 Internet Explorer 中每次调用大约需要 600 毫秒 在其他浏览器中花费的时间可以忽略不计 var nvs currentTab var nvs zoomfield var nvs
  • 异步目录搜索器 (LDAP)

    我正在活动目录中执行长时间搜索 并且非常想使用 DirectorySearcher Asynchronous True 微软提供的文档很少MSDN http msdn microsoft com en us library system d
  • PHP 类:从被调用的方法访问调用实例

    很抱歉这个奇怪的话题 但我不知道如何用其他方式表达它 我正在尝试从调用类访问方法 就像这个例子一样 class normalClass public function someMethod this method shall access
  • Javascript/vue.js接收json

    我正在尝试在我的 vue js 应用程序中接收 json 如下所示 new Vue el body data role company list created function this getJson methods getJson f
  • 将对象重新放入 ConcurrentHashMap 是否会导致“发生在”内存关系?

    我正在与existing具有 ConcurrentHashMap 形式的对象存储的代码 映射内存储了可供多个线程使用的可变对象 根据设计 没有两个线程会尝试同时修改一个对象 我关心的是线程之间修改的可见性 目前 对象的代码在 setter