c# - 从不可变对象(immutable对象)设置拷贝是否可以避免线程损坏?

标签 c# java c++ multithreading scala

关闭。这个问题需要更多 focused 。它目前不接受答案。












想改进这个问题?更新问题,使其仅通过 editing this post 关注一个问题。

8年前关闭。




Improve this question




这是一个类字段,

class someClass {
  Int someClassField = nil
  ...

(请,请(!)忽略可见性问题,这个问题与整体设计有关,而不是语言实现)如果我在网上看教程,我被告知这个字段可以安全地被多个线程使用。当教程说安全时,它们并不意味着一个线程不能干扰另一个线程可见的值。这种干扰可能是本意——场可能是反击。教程的意思是,当一个线程更改此字段时,该字段不会处于不安全状态。占领这个领域,
class someClass {
  List<List> someClassField = new List<Int>()
  ...

据我了解,如果该字段是一个简单的列表,一个线程可能会使其处于不一致的状态(即部分断开连接)。如果另一个线程使用该列表,它将失败——在像 C 这样的语言中,这将是一场灾难。即使阅读也可能失败。

那么,可以要求现场使用的类复制它的状态(复制可以扩展到对不变性的全面辩护,但我保持讨论简单)。如果该类复制了它的状态,那么修改将在字段上的拷贝之外完成,在修改后的新拷贝中进行返回。这个新的、修改后的拷贝可以重新分配给该字段。但是,该分配是否是线程安全的——从某种意义上说,字段的值不能处于不一致的状态——因为新对象对字段的引用分配是原子的?

我忽略了语言引擎是否可能重新排序、缓存等的所有问题。请参阅下面的许多帖子(尤其是 Java,似乎),
  • c# question 有提示
  • Rule of thumb answers 在 Scala 中,但似乎将线性同步与彻底的灾难混淆了?
  • Dark information 关于 Java 的线程可见性问题。一篇文章建议,是的,引用写作是原子的
  • Java question 与此相关。可见性和未成形对象之间的更多相同 Java 混淆
  • immutable-objects-are-thread-safe-but-why Java 问题。听起来像是一个正确的问题,但是什么样的线程安全呢?
  • .net question 偏离航线

  • 我想在较小的范围内解决这个问题......

    最佳答案

    在大多数语言中,对象分配是原子的。

    在这种特定情况下,您需要小心,尽管这样做 x=new X()不能保证在所有语言中 X 在分配之前完全初始化。我不确定 C# 的立场。

    您还必须考虑可见性和原子性。例如,在 Java 中,您需要将变量设置为 volatile,否则在一个线程中所做的更改可能在另一个线程中根本不可见。

    关于c# - 从不可变对象(immutable对象)设置拷贝是否可以避免线程损坏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21045669/

    相关文章:

    c# - 从C#中运行安装程序

    c# - 反射(reflect) .NET 中的类产生的方法仅与修饰符不同

    c++ - 获取使用 vector 的 cygwin_exception::open_stackdumpfile

    c# - 如何获取图像中某些文本的坐标?

    c# - 如何在 Excel 中聚焦或选择单元格

    java - 为什么 JAXB 说 "xxx is an interface, and JAXB can' t 处理接口(interface)”。即使生成的类不是接口(interface)

    java - 通过在 java 中编码获取 URL 响应

    java - neo4j:找不到依赖关系的合格 bean 类型

    c++ - 按照 Visual Studio 的建议,使用 fopen 而不是 fopen_s 有什么错误?

    c++ - C 和 C++ 编程语言的最终链接是什么?