【发布时间】:2012-06-01 06:55:27
【问题描述】:
可能重复:
Java: Why not to start a thread in the constructor? How to terminate?
我习惯于在我的代码上运行FindBugs 以查找错误或不良做法。 今天它抱怨我在类构造函数中启动一个线程。
真的是一件坏事吗?你能解释一下为什么吗?
如果我的课是final的话至少是安全的吗?
编辑:
线程被实现为一个内部类,它只使用启动时已经初始化的主类的字段:
public final class SingletonOuter {
private static SingletonOuter ourInstance = new SingletonOuter();
public static SingletonOuter getInstance() {
return ourInstance;
}
private final SomeOtherClass aField;
private SingletonOuter() {
aField=new SomeOtherClass();
thread=new InnerThread();
thread.start();
}
private boolean pleaseStop;
private synchronized boolean askedStop(){return pleaseStop;}
public synchronized void stop(){
pleaseStop=true;
}
private final InnerThread thread ;
private class InnerThread extends Thread{
@Override public void run() {
//do stuff with aField until askedStop()
}
}
}
编辑:
我最后将线程的开始移到了getInstance方法,以避免引入未来错误的可能性:
public final class SingletonOuter {
private static SingletonOuter ourInstance
public static SingletonOuter getInstance() {
if (ourInstance==null){
ourInstance= = new SingletonOuter();
ourInstance.thread.start();
}
return ourInstance;
}
private final SomeOtherClass aField;
private SingletonOuter() {
aField=new SomeOtherClass();
thread=new InnerThread();
}
...
【问题讨论】:
-
所述问题并非完全重复:我没有逃避这一点,也没有寻求停止我的线程的方法。我将添加代码以澄清
-
既然我们看到了代码,我已经编辑了我的答案。你没问题,但只是因为
aField是final。至少有必要发表一个大评论。见下文。 -
我的回答不正确。虽然 final 字段保证在构造函数返回时被初始化,但如果你在构造函数中 fork 线程,则不能保证
afield将被正确初始化。我改变了我的答案。见:cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#finalRight
标签: java multithreading