I've been searching for justification as for why you should not call a thread's start method inside a constructor for a class. Consider the following code:
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
}
}
ImportantData is some generic box of stuff (presumably important) and MyOperationThread is a subclass of thread that knows how to handle SomeClass instances.
Footnodes:
I totally understand why this is unsafe. If the MyOperationThread tries to access SomeClass.data before the following statement finishes (and data is initialized) I'll get an exception that I was otherwise unprepared for. Or maybe I won't. You can't always tell with threads. In any case, I'm setting myself up for weird, unexpected behavior later.
I don't understand why doing it this way is forbidden territory. At this point, all of SomeClass' members have been initialized, no other member functions that change state have been called, and construction is thus effectively finished.
From what I understand, the reason it's considered bad practice to do this is that you can "leak a reference to an object that has not yet been fully constructed." But the object has been fully constructed, the constructor has nothing left to do but return. I have searched other questions looking for a more concrete answer to this question, and have looked into referenced material as well, but haven't found anything that says "you shouldn't because such and such undesirable behavior," only things that say "you shouldn't."
How would starting a thread in the constructor be conceptually different from this situation:
class SomeClass
{
public ImportantData data = null;
public SomeClass(ImportantData d)
{
// OtherClass.someExternalOperation(this); // Not a good idea
data = d;
OtherClass.someExternalOperation(this); // Usually accepted as OK
}
}
As another aside, what if the class was final?
final class SomeClass // like this
{
...
I saw plenty of questions asking about this and answers that you shouldn't, but none offered explanations, so I figured I'd try to add one that has a few more details.
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…