不可变对象是线程安全的,但为什么呢?

2024-03-12

举例来说,一个线程正在通过创建不可变类的对象来创建和填充不可变类的引用变量,而另一个线程在第一个线程完成并创建不可变类的另一个对象之前启动,那么不可变类的用法不是线程吗不安全?

创建不可变对象还意味着所有字段都必须标记为final。

如果引用了,可能有必要确保正确的行为 新创建的实例从一个线程传递到另一个线程,无需 同步

他们是否想说另一个线程可以将引用变量重新指向不可变类的某个其他对象,这样线程将指向不同的对象,从而导致状态不一致?


实际上,不可变对象始终是线程安全的,但其引用可能不是。

使困惑??你不应该:-

回到基本: 线程安全仅仅意味着两个或多个线程必须在共享资源或对象上协调工作。它们不应该覆盖任何其他线程所做的更改。

现在 String 是一个不可变的类,每当线程尝试更改它时,它最终都会创建一个新对象。因此,即使同一个线程也无法对原始对象进行任何更改,而谈论另一个线程就像去 Sun 一样,但这里的问题是,通常我们使用相同的旧引用来指向新创建的对象。

当我们编写代码时,我们仅使用引用来评估对象中的任何更改。

声明一: 字符串str =“123”; // 最初字符串共享给两个线程

声明2: str = str+"第一个线程"; // 由线程一执行

声明3: str=str+"第二线程"; // 由线程二执行

现在,由于没有同步、易失性或最终关键字告诉编译器跳过使用其智能进行优化(任何重新排序或缓存事物),因此可以按以下方式运行此代码。

  1. 加载Statement2,因此str =“123”+“FirstThread”
  2. 加载Statement3,所以str = "123"+"SecondThread"
  3. 存储Statement3,因此str =“123SecondThread”
  4. 存储Statement2,因此str =“123FirstThread”

最后是引用 str="123FirstThread" 中的值,并且有时如果我们假设幸运的是我们的 GC 线程正在休眠,那么我们的不可变对象仍然原封不动地存在于字符串池中。

因此,不可变对象始终是线程安全的,但它们的引用可能不是。为了使它们的引用线程安全,我们可能需要从同步块/方法访问它们。

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

不可变对象是线程安全的,但为什么呢? 的相关文章

随机推荐

  • Tempus Dominus Bootstrap4 需要 moment.js。 (日期时间选择器)

    我正在尝试使用 Tempus Dominus Bootstrap4 添加 DateTimePicker 但我收到以下错误 I use Laravel as a front end So I use laravel mix 我的刀片文件在下面
  • .htaccess 重写规则中的模式干扰

    在 htaccess 中定义重写规则时 我遇到了模式干扰问题 我试图重写的网站链接是 example com item work gt example com work example com item work tile x gt exa
  • 使用 ActiveAdmin 进行多步骤表单?

    是否可以使用 ActiveAdmin 创建多步骤表单 如果没有 是否可以在提交表单后添加另一个重定向到的页面 不是默认索引 显示或表单页面 我自己也一直在苦恼这个问题 我发现您可以使用 ActiveAdmin 文件中的集合操作添加自己的页面
  • Gwt 2.8-rc1 超级开发模式不适用于 IntelliJ IDEA 2016.2.5

    我的项目在超级开发模式下使用 GWT 2 7 和 2 8 beta1 正确启动 不幸的是 自 2 8 rc1 发布以来 它没有启动 看起来 GWT 项目依赖项配置不正确 IDE IntelliJ IDEA 2016 2 5 C Progra
  • 如何在 karma angularjs 中对 setInterval 进行单元测试

    app directive shuffleBlocks function timeout return link function sco ele att if itemCnt lt 1 return Trigger function fu
  • UITableViewCell 布局在重复使用单元格之前不会更新

    我有一个 UITableView 其中填充了自动调整大小的单元格 UITableView设置相当简单 tableView estimatedRowHeight 70 tableView rowHeight UITableViewAutoma
  • 将 angularjs 值传递给 PHP 变量

    我从 AngularJS 和 ngStorage 开始 我可以成功保存并显示数据 我像以前一样显示值 myobj session 我想将任何存储的值传递到 php 变量中 下面显示的是我的想象逻辑 我知道那是行不通的 我的问题是如何以正确的
  • 如何让 jest 使用 ES6 依赖项

    所以我有一个依赖包 我将其拉入我的 node modules 文件夹中 这个包中有一个像这样的导出 Object
  • PHP sleep() 导致 CPU 使用率高

    我正在运行一个大部分时间处于睡眠状态的 CLI 脚本 每隔 10 秒左右 脚本就会执行一些操作 问题是 脚本在睡眠时 CPU 使用率为 94 我设置的方法是 while 1 sleep 10 doStuff 虽然这按预期工作 但存在一个明显
  • 字符+字符=整数?为什么?

    为什么要加两个char在 C 中结果为int type 例如 当我这样做时 var pr R G B Y P the pr变量变成int类型 我希望它是一个string类型值为 RGBYP 为什么C 要这样设计呢 默认实现不是添加两个cha
  • 从Excel VBA的下拉列表中选择特定项目

    我正在为我的办公室设计一个仪表板 这一切都有效 但我想添加一个选项 而不是在下拉列表中搜索 250 多个项目 您还可以单击一个单元格 下拉列表将更改为该值 并且分配的宏将为该下拉列表运行 到目前为止 我不知道如何让 vba 从下拉列表中选择
  • 具有列表视图的 Android 小部件正在刷新具有丑陋的短“闪烁”效果的项目

    我想制作一个带有 ListView 的小部件 您可以在其中添加 listItems 来显示计数器计时器 以查看您有多少时间来处理某个事件 这是我第一次使用小部件 我不知道我的方法是好还是坏 到目前为止我得到了这个 AppWidgetProv
  • Javascript - 所有嵌套的 forEach 循环完成后的回调

    我确信这是一个相当简单的任务 但我现在无法全神贯注 我有一组嵌套的 forEach 循环 当所有循环运行完毕时 我需要一个回调 我愿意使用 async js 这就是我正在处理的 const scanFiles function accoun
  • 如何使用 BiWeekly 库和 Java Mail API 创建现有事件并发送更新?

    我在用着BiWeekly http sourceforge net projects biweekly 库来创建 VEVENT 然后使用以下命令发送它Java 邮件 API https java net projects javamail
  • 具有动态数量的并行消费者的 Kafka 工作队列

    我想用Kafka来 分工 我想将工作实例发布到某个主题 并运行由相同使用者组成的云来处理它们 当每个消费者完成其工作时 它将从该主题中提取下一个工作 每项工作只能由一个消费者处理一次 处理工作非常昂贵 因此我需要在许多机器上运行许多消费者才
  • New (std::nothrow) 与 try/catch 块中的 New

    学习后我做了一些研究new 不像malloc 我习惯了 分配失败时不会返回 NULL 并且发现有两种不同的方法来检查 new 是否成功 这两种方式是 try ptr new int 1024 catch std bad alloc exc
  • PayPal 自适应付款错误 您无权隐式执行此付款

    我有一个发送付款的简单应用程序 该应用程序在沙箱中运行良好 实时经典应用程序的应用程序 ID 已获得批准 显示为 自动批准 但当我输入实时凭据时 它返回错误 您无权隐式执行此付款 发送 XML 到端点https svcs paypal co
  • 在钩子 woocommerce_checkout_order_processed 中获取订单详细信息

    add action woocommerce checkout order processed send order fax function send order fax order id print r REQUEST die 我想在这
  • JavaScript 异步返回值/使用 jQuery 赋值[重复]

    这个问题在这里已经有答案了 我有以下 jQuery 函数 我正在尝试返回此处显示的 GUID 值alert 警报工作正常并且值已填充 但是我似乎无法将其分配给变量并返回其值 最终我需要访问其他函数中的GUID值等 我尝试过的所有内容都仅显示
  • 不可变对象是线程安全的,但为什么呢?

    举例来说 一个线程正在通过创建不可变类的对象来创建和填充不可变类的引用变量 而另一个线程在第一个线程完成并创建不可变类的另一个对象之前启动 那么不可变类的用法不是线程吗不安全 创建不可变对象还意味着所有字段都必须标记为final 如果引用了