- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
好吧,考虑下面给出的不可变类 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)
}
}
线程 A
将 obj
视为 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/
我是一名优秀的程序员,十分优秀!