I understand that in general it is a bad idea to start a new thread in a constructor because it could let this escape before it is fully constructed. For example:
public final class Test {
private final int value;
public Test(int value) throws InterruptedException {
start();
this.value = value;
}
private void start() throws InterruptedException {
for (int i = 0; i < 10; i++) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Construction OK = " + Boolean.toString(Test.this.value == 5));
}
}).start();
}
}
public static void main(String[] args) throws InterruptedException {
Test test = new Test(5);
}
}
This prints (obviously not the same every run):
Construction OK = false
Construction OK = false
Construction OK = false
Construction OK = false
Construction OK = false
Construction OK = false
Construction OK = false
Construction OK = true
Construction OK = true
Construction OK = true
Now IF the start method is the last statement of the constructor AND reordering is prevented by using a synchronized block around the final value initialisation, is there still a risk associated with starting threads from the constructor?
public Test(int value) throws InterruptedException {
synchronized (new Object()) { // to prevent reordering + no deadlock risk
this.value = value;
}
start();
}
EDIT
I don't think this has been asked before in the sense that the question is more specific than just "Can I start threads in a constructor": the threads are started in the last statement of the constructor which means the object construction is finished (as far as I understand it).
Yes there is, because Test could be subclassed and then start() will be executed before the instance is created. The subclasses constructor may have something more to do.
So the class should be final at least.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With