【问题标题】:Does happens before Program order rule work in constructors?程序顺序规则在构造函数中起作用之前是否发生?
【发布时间】:2013-12-13 16:29:48
【问题描述】:

是否真的可以在构造函数中创建的线程中查看部分构造的对象,因为缺少同步和泄漏这个实例?

当然,除了有子类的情况,或者我们正在使用 clone 或类似的东西进行隐式构造 - 所以我们假设该类是 final 并且它是否已完全初始化在调用其他线程之前在调用构造函数的线程中。

据我了解,以下 hb() 规则适用,

  • 线程中的每个操作都发生在该线程中的每个操作之前 在节目顺序后面出现(节目顺序规则)

  • 线程上的 start() 调用发生在已启动线程中的任何操作之前。

  • 如果hb(x, y) 和hb(y, z),那么hb(x, z)

这是否意味着以下代码在技术上是线程安全的(我取自类似问题Why shouldn't I use Thread.start() in the constructor of my class?,也有类似问题Why it is bad practice to create a new thread on constructors?,ps 我希望这个一个不会因为重复而关闭)

final class SomeClass
{
    public ImportantData data = null;
    public Thread t = null;

    public SomeClass(ImportantData d)
    {
        t = new MyOperationThread();

        // t.start(); // Footnote 1

        data = d;

        t.start();    // Footnote 2
    }
}

附:显然 data 字段在这里缺乏封装,但是这个问题是关于线程 t 中对象的状态可见性。

【问题讨论】:

  • 实际上你应该没问题,理论上在线程的run方法中调用this.data是未定义的,因为this可能还没有初始化。
  • 您的代码示例引用了脚注。他们在哪里?
  • 脚注实际上是我所指的问题。 stackoverflow.com/questions/11834173/why-shouldnt-i-use-thread-start-in-the-constructor-of-my-class

标签: java multithreading concurrency jls


【解决方案1】:

是的,确实如此。规范明确writes

启动线程的动作与它启动的线程中的第一个动作同步。

当然,当构造函数完成时,不能保证对象被完全初始化,因为构造函数可以调用其他构造函数——要么通过explicit constructor invocation statement,要么因为隐式调用超类默认构造函数。因此,从构造函数中泄漏this 是相当脆弱的——使用单个或多个线程。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-19
    • 2022-07-29
    • 1970-01-01
    • 2014-01-28
    相关资源
    最近更新 更多