问题
Consider two threads: threadA and threadB. (E.g. let threadA be the UI thread, and let threadB an own subclass of Thread.) Regarding data visibility, is it safe to instantiate a class in threadA, pass it to the constructor of threadB, and then use it exclusively from threadB? Let me clarify this with code. (Note that the code is simplified, so this architecture makes sense in the real application in its actual form.)
public class SomeClass {
public SomeClass(....) {
// initialization
}
}
public class MyCustomThread extends Thread {
public MyCustomThread(SomeClass someClass) {
mSomeClass = someClass;
}
@Override
public void run() {
// operate on mSomeClass
}
}
And the method that starts everything is as follows (its location is irrelevant). This is called by 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
}
I know that constructors are not allowed to be synchronized, and no synchronized code is needed inside it (because the this reference -- unless leaked out -- is not available to other threads until the class is constructed in its creator thread). So my question is about data visibility: is the code safe, provided I don't access someClass (and any of its referenced data) from threadA after threadB.start() is called?
In other words, will threadB.run() see the most up-to-date versions of someClass data (such as fields, internal references, etc.)? My guess: since there will be no external change on someClass after threadB accesses someClass for the first time, threadB must see the correct values, because it can't have cached copies from before. So, for the above reason, I don't need to access someClass in a synchronized block from threadB.run(). (Again, note that it's guaranteed that threadA doesn't access someClass after threadB is started.)
回答1:
If you're saying that, after threadB.start(), the instance referred to by someClass will no longer be modified by any other thread: yes, threadB.run() will see the latest version.
There's really no concurrency/race-condition that could occur in this scenario. Everything is happening sequentially, you simply have objects that are Threads which I think might be causing you to be slightly paranoid :).
来源:https://stackoverflow.com/questions/11321005/instantiating-a-class-then-using-it-in-another-thread