gpt4 book ai didi

java - 不变性是否保证线程安全?

转载 作者:行者123 更新时间:2023-11-29 09:43:42 24 4
gpt4 key购买 nike

好吧,考虑下面给出的不可变类 Immutable:

public final class Immutable
{
final int x;
final int y;
public Immutable(int x,int y)
{
this.x = x;
this.y = y;
}
//Setters
public int getX()
{
return this.x;
}
public int getY()
{
return this.y;
}
}

现在我在 Sharable 类中创建一个 Immutable 的对象,它的对象将被多个线程共享:

public class Sharable
{
private static Immutable obj;
public static Immutable getImmutableObject()
{
if (obj == null) --->(1)
{
synchronized(this)
{
if(obj == null)
{
obj = new Immutable(20,30); ---> (2)
}
}
}
return obj; ---> (3)
}
}

线程 Aobj 视为 null 并移至同步块(synchronized block)并创建对象。现在,由于 Java 内存模型 (JMM) 允许多个线程在对象初始化开始后但结束前观察​​该对象。 因此,线程 B 可以看到写入obj 发生在写入 Immutable 的字段之前。因此,Thread B 可以看到部分构造的 Immutable,它很可能处于无效状态,并且其状态可能会在以后意外更改。

这不是让 Immutable 成为非线程安全的吗?


编辑
好的,在对 SO 进行大量查找并深入了解一些评论之后,我了解到您可以安全地在线程之间共享对不可变对象(immutable对象)的引用在构造对象之后。此外,正如@Makoto 所提到的,通常需要将包含其引用的字段声明为易变的以确保可见性。此外,如 @PeterLawrey 所述,将对不可变对象(immutable对象)的引用声明为 final 会使该字段成为 thread-safe

最佳答案

So, Thread B could see the write to objas occurring before the writes to the fields of the Immutable. Hence Thread B could thus see a partially constructed Immutable that may well be in an invalid state and whose state may unexpectedly change later.

在 Java 1.4 中,这是真的。在 Java 5.0 及更高版本中,final 字段在构造后是线程安全的。

关于java - 不变性是否保证线程安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25224033/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com