代码之家  ›  专栏  ›  技术社区  ›  Jorge Córdoba

不可变对象总是线程安全的吗?

  •  1
  • Jorge Córdoba  · 技术社区  · 16 年前

    可以安全地假设使用或传递不可变对象始终是线程安全的吗?

    4 回复  |  直到 14 年前
        1
  •  10
  •   LukeH    16 年前

    对如果一个对象是真正不可变的,没有 内部的 如果发生突变,则对象本身将是线程安全的。

    (是否处理对象并以线程安全的方式传递它是另一回事!)

    我说的“内部突变”是什么意思?

    许多对象从外部看起来是不可变的,例如,没有属性设置器或其他成员会更改 触发突变——但这并不意味着对象的私有内部无法更改。

    这就是为什么记录对象和/或其成员的可变性和线程安全性非常重要的原因。否则,如果不仔细检查内部(这是一个实现细节,可能随时会更改),对象的使用者就无法发现这一点。

        2
  •  2
  •   FacticiusVir    16 年前

    这取决于你所说的线程安全是什么意思;作为 Eric Lippert's blog

    我怀疑,对于您心目中“线程安全”的含义,答案是肯定的。但请记住,不变的对象不是金子弹;它们不会使您对线程交互免疫,它们只是在单个实例中提供一致性。

        3
  •  1
  •   Stefan Steinegger    16 年前

    正确回答这个问题:不。

    您不能假设不可变对象是 总是 线程安全。

    但很可能是这样。另见关于Lukes答案的讨论。

    例如:对方法或属性getter的访问可能会触发调用方不知道的初始化((例如,延迟初始化)此初始化必须显式实现线程安全。

        4
  •  0
  •   peterchen    16 年前

    其次,在构造过程中,对象会被修改——由于CPU上的优化和指令重新排序,内存的写入顺序不一定与源代码中的顺序相同。

    这意味着,在没有同步的情况下,另一个线程可能在对象完全构造之前已经看到了对该对象的有效引用。