所以我有一个“棘手”的问题,我希望看到别人的意见。
我正在编写一个组件,它扩展了一个JPanel并做了一些自定义的东西。 在那个组件里面我有一个Thread,就像这样永远循环:
//chat thread
Thread chat_thread = new Thread(new Runnable(){
public void run(){
while(true){
//get chat updates
}
}
});
chat_thread.start();
所以问题是,当remove()
方法将组件从其父组件中删除时,
这个线程是否仍然存在,或者在删除组件时它是否会死亡?
编辑: 感谢所有回复,确实线程没有终止删除它的启动器,所以为了从另一个组件终止这个线程,我做了以下事情:
Set<Thread> t = Thread.getAllStackTraces().keySet();
Iterator it = t.iterator();
while(it.hasNext()){
Thread t2 = (Thread)it.next();
if(t2.getName().equals("chat_thread")){
t2.interrupt();
}
}
首先使用Thread.setName()方法为我的线程创建一个名称。 谢谢!
答案 0 :(得分:4)
它仍然活着。正在运行的线程构成GC的根。从根开始的一系列引用可以访问的所有内容都不符合GC的条件。这意味着,BTW,您的面板也不会被GC,因为线程持有对面板的隐式引用(EnclosingPanel.this
)。
当您不希望它再次运行时,您需要确保停止该线程。
答案 1 :(得分:3)
此线程永远不会死(除非它崩溃或自行终止)。
启动它的线程或包含它的组件发生了什么并不重要。
如果您不想挂起JVM,可以将其声明为守护程序线程。然后它会在其他一切都关闭时关闭。要获得更多控制,您需要确保在适当的时候在自己的代码中终止线程。
答案 2 :(得分:1)
线程在完成其工作或interrupt
之前不会消亡。
答案 3 :(得分:1)
线程将在退出run()方法时终止,所以当通过remove()方法从其父组件中删除组件时,线程永远不会终止。
答案 4 :(得分:0)
看一下Component.removeNotify。在组件中,保留指向线程的指针:
public class MyPanel extends JPanel {
private Thread thread = ...;
public void removeNotify() {
super.removeNotify();
thread.interrupt();
}
}
当awt决定删除组件的本地对等体(即支持awt组件的windows或linux组件)时,awt本身会调用此方法。根据javadoc:
通过销毁本机屏幕资源使此组件无法显示。 该方法由内部工具包调用,不应由程序直接调用。重写此方法的代码应调用super.removeNotify作为覆盖方法的第一行。