不可变对象的真正好处是什么

2024-02-27

我总是听到人们说,在使用多个线程时管理不可变对象更容易,因为当一个线程访问不可变对象时,不必担心另一个线程正在更改它。

那么,如果我有一个公司所有员工的不可变列表并且雇用了一名新员工,会发生什么情况?在这种情况下,必须复制不可变列表,并且它的新副本必须包含另一个员工对象。然后,对员工列表的引用应定向到新列表。

当这种情况发生时,列表本身不会改变,但对此列表的引用会改变,因此代码“看到”不同的数据。

如果是这样,我不明白为什么不可变对象使我们在使用多线程时生活更轻松。我缺少什么?


可变数据并发更新的主要问题是,线程可能会感知来自不同版本的变量值,即,在单个更新时,新旧值的混合,形成不一致的状态,违反了这些变量的不变量。

例如,参见 Java 的ArrayList。它有一个int保存当前大小的字段和对数组的引用,该数组的元素是对所包含对象的引用。这些变量的值必须满足某些不变量,例如如果大小非零,则数组引用永远不会null并且数组长度总是大于或等于大小。当看到这些变量的不同更新值时,这些不变量不再成立,因此线程可能会看到从未以这种形式存在的列表内容,或者因虚假异常而失败,报告应该不可能的非法状态(例如NullPointerException or ArrayIndexOutOfBoundeException).

请注意,线程安全或并发数据结构仅解决有关数据结构内部的问题,因此操作不会再因虚假异常而失败(关于集合的状态,我们还没有讨论所包含元素的状态),但是操作迭代这些集合或以任何形式查看多个包含的元素,仍然可能会观察到有关包含的元素的不一致状态。这也适用于先检查然后执行的反模式,其中应用程序首先检查条件(例如使用contains),然后对其进行操作(例如获取、添加或删除元素),而条件可能会在中间发生变化。

相反,处理不可变数据结构的线程可能会处理其过时的版本,但属于该结构的所有变量彼此一致,反映相同的版本。执行更新时,您不需要考虑排除其他线程,这根本没有必要,因为其他线程看不到新的数据结构。发布新版本的整个任务简化为发布对数据结构新版本的根引用的任务。如果您无法阻止其他线程处理旧版本,则可能发生的最糟糕的情况是您之后可能必须使用新数据重复操作,换句话说,在最坏的情况下,这只是一个性能问题。

这对于具有垃圾收集功能的编程语言来说很顺利,因为它们允许新的数据结构引用旧对象,只需替换更改的对象(及其父对象),而无需担心哪些对象仍在使用中,哪些没有使用。

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

不可变对象的真正好处是什么 的相关文章

  • C# 是否可以中断 ThreadPool 内的特定线程?

    假设我已将一个工作项排入队列ThreadPool 但是如果没有要处理的数据 从BlockingQueue 如果队列为空并且队列中不再有工作 那么我必须调用Thread Interrupt方法 如果我想中断阻塞任务 但是如何用 a 做同样的事
  • 无锁算法中的 ABA

    我明白了ABA http en wikipedia org wiki ABA problem问题 但我无法理解的是 他们说在语言中自动垃圾收集它可能不会展示 所以我的问题是 自动垃圾收集如何防止ABA问题的发生 在java中是否可能 如果可
  • Intel 64 和 IA-32 上的 MESI 有何意义

    MESI 的要点是保留共享内存系统的概念 然而 对于存储缓冲区 事情就变得复杂了 一旦数据到达 MESI 实现的缓存 下游内存就会保持一致 然而 在此之前 每个核心可能对内存位置 X 中的内容存在分歧 具体取决于每个核心的本地存储缓冲区中的
  • 没有公平性的DelayQueue有问题吗?

    在 Java 7 中 DelayQueue 的实现使用没有公平策略的 ReentrantLock 从长远来看 这是一个问题吗 线程会因此而饿死吗 Thanks 如果您考虑ScheduledThreadPoolExecutor 或任何其他生产
  • 使用多个构造函数创建不可变类

    我正在阅读这一页 https docs oracle com javase tutorial essential concurrency imstrat html关于在 Java 中创建不可变类 并决定根据页面上概述的规范修改我正在编写的类
  • 我是否需要关心异步 Javascript 的竞争条件?

    假设我加载了一些我知道在将来某个时候会调用的 Flash 影片window flashReady并将设置window flashReadyTriggered true 现在我有一个代码块 我想在闪存准备好时执行它 我希望它立即执行 如果wi
  • 用惯用的 Scala 更新大型数据结构

    我已经尝试 Scala 一段时间了 并且经常遇到支持不可变数据结构的建议 但是当你有一个像这样的数据结构时3D 场景图 大型神经网络或任何具有大量需要频繁更新的对象的东西 对场景中的对象进行动画处理 训练神经网络 这似乎是 运行时效率极低
  • 在 Swift async/await 中,我可以使用 Lock 还是 Semaphore

    这不是问题 这是一个想寻求帮助以及专业指导的问题 根据文档 Sendable 类型可以在 Swift Concurrency 中安全地传递 在旧项目中并非所有类型都是可发送的 并且可能使用Cocoa类型 但它们是线程安全的 例如 class
  • 并发:C++11 内存模型中的原子性和易失性

    全局变量在 2 个不同内核上的 2 个并发运行的线程之间共享 线程对变量进行写入和读取 对于原子变量 一个线程可以读取过时的值吗 每个核心可能在其缓存中具有共享变量的值 并且当一个线程写入缓存中的其副本时 不同核心上的另一个线程可能会从其自
  • 插入并发问题-多线程环境

    我有一个问题 即使用完全相同的参数在完全相同的时间调用相同的存储过程 存储过程的目的是获取记录 如果存在 或创建并获取记录 如果不存在 问题是两个线程都在检查记录是否存在并报告错误 然后都插入新记录 在数据库中创建重复记录 我尝试将操作保留
  • 断点会停止所有线程吗?

    如果我的程序中有两个线程同时运行 并在其中一个线程上设置了断点 那么当遇到此断点时 另一个线程也会停止 还是会继续执行 我用 Java 编写并使用 NetBeans 断点可以选择它们的行为方式 挂起单个线程或所有线程
  • 使用 Akka 1.3 的 actor 时,我需要注意生产者-消费者速率匹配吗?

    使用 Akka 1 3 时 我是否需要担心当生成消息的 Actor 生成消息的速度比使用消息的 Actor 的处理速度快时会发生什么 如果没有任何机制 在长时间运行的进程中 队列大小将增大以消耗所有可用内存 The doc http doc
  • 异步迭代器

    我有以下代码 while slowIterator hasNext performLengthTask slowIterator next 由于迭代器和任务都很慢 因此将它们放入单独的线程中是有意义的 这是对迭代器包装器的快速而肮脏的尝试
  • Condition 接口中的 signalAll 与对象中的 notificationAll

    1 昨天我才问过这个问题条件与等待通知机制 https stackoverflow com questions 10395571 condition vs wait notify mechanism 2 我想编辑相同的内容并在我的问题中添加
  • 基于值的类混乱

    我正在寻求一些澄清基于值的类的定义 https docs oracle com javase 8 docs api java lang doc files ValueBased html 我无法想象 最后一个要点 6 应该如何与第一个要点一
  • Scala:var List 与 val MutableList

    在 Odersky 等人的 Scala 书中 他们说使用列表 我还没有从头到尾读过这本书 但所有的例子似乎都使用了 val List 据我了解 还鼓励人们使用 vals 而不是 vars 但在大多数应用程序中 使用 var List 或 v
  • scala.concurrent.blocking - 它实际上做了什么?

    我花了一段时间学习 Scala 执行上下文 底层线程模型和并发性的主题 你能解释一下通过什么方式吗scala concurrent blocking 调整运行时行为 and 可以提高性能或避免死锁 如中所述scaladoc http www
  • 初始化 ConcurrentHashMap 值的最快方法

    ConcurrentHashMap 通常在并发环境中用于聚合某个键下的某些事件 例如计算某些字符串值的命中数 如果我们事先不知道密钥 我们需要有一个好的方法来根据需要初始化密钥 它应该在并发性方面快速且安全 这个问题的最佳模式 就效率而言
  • 如何使 ScheduledExecutorService 在计划任务取消时自动终止

    我正在使用一个ScheduledExecutorService如果网络连接已打开超过几个小时 则关闭该连接 然而 在大多数情况下 网络连接在超时之前就关闭了 所以我取消了ScheduledFuture 在这种情况下 我还希望执行程序服务终止
  • Java 空值检查

    我有一个thread1 if object null object play 和另一个thread2可以写null into object随时参考 我将同时运行这些线程 我知道thread2可以重写object后参考null检查并会抛出Nu

随机推荐

  • Python - 使用 ffprobe 获取视频的持续时间

    我是Python新手 我正在尝试使用以下命令获取文件视频的持续时间 以秒为单位 ffprobe 调用如下指令 ffprobe i video mp4 show entries format duration v quiet of csv p
  • NDB 查询以字符串开头的结果

    使用 Google App Engine NDB 我希望查询以用户输入的字符串开头的所有项目 例子 abc 123 abcdefg 123abc 查询 abc 应返回 abc 123 abcdefg 但是 不是 123abc 因为它不 以
  • 在带有数字的文本框中自动添加逗号 (,)

    我当前的编码在有 4 个或更多数字时添加逗号 但不是 1101 1 101 我的代码正在这样做 1101 110 1 我希望它格式化并将逗号放在前面 我的 JavaScript
  • 无法在 Windows 7 / OSX 上安装 jasmine-core

    我正在尝试安装karma jasmine在 Windows 7 Git Bash 上 根据以下指南 http karma runner github io 0 13 intro installation html http karma ru
  • Bing Api 针对简单单词“游戏”返回 41 个结果

    我正在尝试在我的网站中实施 bing 搜索 我需要 JSON 格式的搜索结果 这是我正在使用的网址 我正在尝试搜索一个简单的文字游戏 我应该得到数百万个结果 但我总共得到 41 以下是我的结果的一部分 SearchResponse Vers
  • ASP.NET DropDownList 上的 FindByValue

    我在自定义用户控件中有以下代码 其中包含名为 ddlAggerationUnitId 的 DropDownList DropDownList 在 Page Load 事件上进行数据绑定 值 设置为 40 并且它确实存在 如果我删除 set
  • 线程安全枚举单例

    枚举非常适合创建单例 我知道枚举方法不是线程安全的 所以我尝试使其成为线程安全的 任何人都可以确认此实施是否正确 这么多地方用static和volatile好不好 可以优化吗 由于内部类是私有的 所以我必须在枚举中创建函数来访问内部类功能
  • 如何检查 PostgreSQL 公共模式是否存在?

    运行以下查询 SELECT exists SELECT schema name FROM information schema schemata WHERE schema name public AS schema exists 我总是越来
  • R中按距离聚类

    我有一个整数向量 我希望将其分成簇 以便任何两个簇之间的距离大于下限 并且在任何簇内 两个元素之间的距离小于上限 例如 假设我们有以下向量 1 4 5 6 9 29 32 36 并将上述下界和上限分别设置为 19 和 9 下面的两个向量应该
  • Team Foundation Server 合并未合并

    为什么 TFS 不想归还我的旧文件 Dev Branch Main Branch Merging Dev to Main Edit 鉴于下面的第一个答案和更多调查 我相信我正在尝试完成整个分支覆盖 这可能吗 这是一件好事 我认为最好的办法是
  • 编译 SASS 时出现预期换行错误

    我遇到的问题是我的 SASS 无法编译并且它向我显示相同的错误 Expected NewLine topper h3 text align center text decoration underline list group active
  • 在自定义 keras 损失中使用 keras 模型

    我有一个名为的常规 keras 模型e我想比较两者的输出y pred and y true在我的自定义损失函数中 from keras import backend as K def custom loss y true y pred re
  • (iPhone) selectedRange 用于不可编辑的 UITextView (或其他点击处理方法?)

    我正在使用一个UITextView保存静态内容 中文意思是字符都是固定宽度的 我想让用户单击文本中的某个字符并显示该字符的字典信息 我知道所有与缺乏复制和粘贴相关的问题 但我希望有一种方法可以做到这一点 而无需等待 iPhone 3 0 固
  • 是否有可能在源代码中抑制 sonarcloud 的警告?

    我面临一些声纳云警告的问题 这些警告在最近的将来不会得到解决 现在应该被禁用 这些警告是由 sonarcloud 在 CI 构建过程中发出的 没有任何本地分析器 有没有办法在项目 文件 类和 或方法级别上抑制源代码中的某些特定警告 官方文档
  • 在 NativeModules 中添加对象

    我想用https github com dgladkov react native image rotate https github com dgladkov react native image rotate在反应本机项目中 我用它下载
  • Java JTextPane RTF 保存

    我有以下代码尝试将 JTextPane 的内容保存为 RTF 虽然下面的代码创建了一个文件 但它是空的 关于我做错了什么有什么建议吗 像往常一样 不要忘记我是初学者 if option JFileChooser APPROVE OPTION
  • 在python中计算直方图峰值

    在Python中 如何计算直方图的峰值 我试过这个 import numpy as np from scipy signal import argrelextrema data 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 1
  • 如何在Python中将元组转换为多层嵌套字典?

    我有一个以下格式的元组 639283 298290710 1385 639283 298290712 1389 639283 298290715 1395 745310 470212995 2061 745310 470213821 371
  • 将 MySql 从 Windows 服务器迁移到 Linux

    从旧的 Win2003 服务器迁移到新的 VM 服务器 我们选择 Win 或 Linux 如果我们使用 Linux 转换当前表会有任何问题吗 将 MySQL Windows 迁移到相同版本的 MySQL Linux 您可以按如下方式 mys
  • 不可变对象的真正好处是什么

    我总是听到人们说 在使用多个线程时管理不可变对象更容易 因为当一个线程访问不可变对象时 不必担心另一个线程正在更改它 那么 如果我有一个公司所有员工的不可变列表并且雇用了一名新员工 会发生什么情况 在这种情况下 必须复制不可变列表 并且它的