实例化一个类,然后在另一个线程中使用它

时间:2012-07-04 00:31:46

标签: java android multithreading constructor

考虑两个线程: threadA threadB 。 (例如,让 threadA 成为UI线程,让 threadB 成为Thread的子类。)关于数据可见性,是吗?安全地在 threadA 中实例化一个类,将它传递给 threadB 的构造函数,然后从 threadB 中专门使用它?让我用代码澄清一下。 (请注意,代码已经过简化,因此这种架构在实际应用中以其实际形式有意义。)

public class SomeClass {
    public SomeClass(....) {
       // initialization
    }
}

public class MyCustomThread extends Thread {
    public MyCustomThread(SomeClass someClass) {
        mSomeClass = someClass;
    }

    @Override
    public void run() {
           // operate on mSomeClass         
    }
}

启动所有内容的方法如下(其位置无关紧要)。这由 threadA 调用。

public void launchThread() {
   SomeClass someClass = new SomeClass();
   MyCustomThread threadB = new MyCustomThread(someClass); // MyCustomThread is a subclass of Thread
   threadB.start();
   // After this point, threadA never accesses someClass,
   // and only threadB is operating on it
}

我知道不允许构造函数同步,并且内部不需要同步代码(因为 this 引用 - 除非泄露 - 在该类之前不可用于其他线程是在其创建者线程中构建的)。所以我的问题是关于数据可见性:代码是安全的,前提是我在调用someClass后不从 threadA 访问threadB.start()(及其任何引用的数据)?

换句话说,threadB.run()会查看最新版本的someClass数据(例如字段,内部参考资料等)吗?我猜:由于 threadB 首次访问someClasssomeClass上没有外部更改, threadB 必须看到正确的值,因为它不能拥有之前的缓存副本。因此,出于上述原因,我无需在someClass的同步块中访问threadB.run()。 (同样,请注意, threadB 启动后, threadA 无法访问someClass

1 个答案:

答案 0 :(得分:2)

如果您这样说,在threadB.start()之后,someClass引用的实例将不再被任何其他线程修改:是的,threadB.run()将看到最新版本。

在这种情况下,确实没有并发/竞争条件。一切都按顺序发生,你只需要Thread s的对象,我认为这可能会让你有点偏执:)。