gpt4 book ai didi

java - java多线程中的安全构造

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:09:22 25 4
gpt4 key购买 nike

这是在 java 多线程中安全构造实践的上下文中。我正在阅读 JCIP 书,有人可以在下面解释一下吗:

an object is in a predictable, consistent state only after its constructor returns, so publishing an object from within its constructor can publish an incompletely constructed object. This is true even if the publication is the last statement in the constructor.

在这里我想了解具体的部分'即使发布是这样也是如此 构造函数中的最后一条语句'

我知道从构造函数启动一个线程是不安全的,但是当它是构造函数中的最后一条语句时它也不安全吗?

我的猜测是关于为什么它不安全的原因是,JVM 可以对语句进行重新排序,而最后一个语句将不再是最后一个。请对此发表评论或纠正我的理解。

编辑:有问题的是,启动线程的意思是泄漏 this 引用。这种泄漏可能通过多种方式发生,例如发布事件或启动线程。

最佳答案

这里有两个见解可能对您有所帮助。首先,出于同步目的,构造函数(大部分)与任何其他方法一样;也就是说,它本身并不提供任何(除非如下所述)。其次,线程安全始终存在于各个操作之间。

假设您有以下构造函数:

MyClass() {
this.i = 123;
MyClass.someStaticInstance = this; // publish the object
}

// and then somewhere else:
int value = MyClass.someStaticInstance.i;

问题是:最后一个表达式能做什么?

  • 它可以抛出 NullPointerException,如果 someStaticInstance尚未设置。
  • 它也可能导致 value == 123
  • 但有趣的是,它导致value == 0

最后一点的原因是 Action 可以重新排序,构造函数在这方面并不特殊。让我们仔细看看所涉及的操作:

  • A.为新实例分配空间,并将其所有字段设置为其默认值(0 表示 int i )
  • B.设置 <instance>.i = 123
  • C.设置 someStaticInstance = <instance>
  • D.读书someStaticInstance ,然后是它的 i

如果你稍微重新排序,你可以得到:

  • A.为新实例分配空间,并将其所有字段设置为其默认值(0 表示 int i )
  • C.设置 someStaticInstance = <instance>
  • D.读书someStaticInstance ,然后是它的 i
  • B.设置 <instance>.i = 123

这就是你的 -- value是 0,而不是 123。

JCIP 还警告您泄漏可能以微妙的方式发生。例如,假设您没有明确设置 someStaticInstance字段,而只是调用 someListener.register(this) .您仍然泄露了引用,并且您应该假设您注册的监听器可能会对它做一些危险的事情,比如将它分配给 someStaticInstance .

即使i也是如此字段是最终的。您可以从 final 字段获得一些线程安全性,但前提是您不泄漏 this来自构造函数。具体来说,在 JLS 17.5 ,它说:

An object is considered to be completely initialized when its constructor finishes. A thread that can only see a reference to an object after that object has been completely initialized is guaranteed to see the correctly initialized values for that object's final fields.

保证“只有在对象完全初始化后才能看到对该对象的引用”的唯一方法是不从其构造函数中泄漏引用。否则,您可以想象一个线程读取 MyClass.someStaticInstance在设置字段之后,但在 JVM 将构造函数识别为已完成之前。

关于java - java多线程中的安全构造,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48171140/

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