Я понимаю, что в общем случае плохая идея начинать новый поток в конструкторе , потому что он может позволить этому экранированию до того, как он будет полностью создан.Например:
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);
}
}
Это печатает (очевидно, не то же самое при каждом запуске):
Конструкция OK = false
Конструкция OK = false
Конструкция OK = false
Конструкция OK = false
Конструкция OK = false
Конструкция OK = false
Конструкция OK = false
Конструкция OK = true
Конструкция OK = true
Конструкция OK = true
Now IF метод start
является последним оператором конструктора AND Переупорядочение предотвращается с помощью синхронизированного блока вокруг инициализации конечного значения,все еще существует риск, связанный с запуском потоков из конструктора?
public Test(int value) throws InterruptedException {
synchronized (new Object()) { // to prevent reordering + no deadlock risk
this.value = value;
}
start();
}
EDIT
Я не думаю, что это было задано ранее в том смысле, что вопрос более конкретенчем просто «Могу ли я запустить потоки в конструкторе»: потоки запускаются в последнем утверждении конструктора, что означает, что строительство объекта завершено (насколько я понимаю).