1

考虑两个线程:threadAthreadB。(例如,让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引用——除非泄露出去——在类在其创建者线程中构造之前对其他线程不可用)。所以我的问题是关于数据可见性:如果我在调用threadA后不访问someClass(及其任何引用的数据),代码是否安全?threadB.start()

换句话说,会threadB.run()看到最新版本的someClass数据(如字段、内部引用等)吗?我的猜测:因为在threadB第一次访问之后不会有外部变化,所以someClassthreadB必须看到正确的值,因为它不能从 before 缓存副本。因此,出于上述原因,我不需要从. (同样,请注意,在threadB启动后,可以保证threadA不会访问。)someClasssomeClassthreadB.run()someClass

4

1 回答 1

2

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

在这种情况下确实不会发生并发/竞争条件。一切都是按顺序发生的,您只是拥有Threads 的对象,我认为这可能会导致您有点偏执:)。

于 2012-07-04T00:42:29.463 回答