4

所以我有一个“棘手”的问题,我想看看人们的意见。

我正在编写一个组件,它扩展了一个 JPanel 并做一些自定义的东西。在那个组件里面我有一个线程,它像这样永远循环:

//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() 方法为我的线程创建一个名称。谢谢!

4

5 回答 5

4

该线程永远不会死亡(除非它崩溃或自行终止)。

启动它的线程或包含它的组件发生了什么并不重要。

如果您不想挂起JVM,您可以将其声明为守护线程。然后它会在其他所有操作时关闭。为了获得更多控制,您需要确保在适当的时间终止您自己的代码中的线程。

于 2012-06-09T06:49:22.300 回答
4

它仍然会活着。正在运行的线程构成 GC 的根。从根开始的引用链中可访问的所有内容都不符合 GC 条件。顺便说一句,这意味着您的面板也不会被 GC,因为线程包含对面板 ( EnclosingPanel.this) 的隐式引用。

当您不想再运行该线程时,您需要确保停止该线程。

于 2012-06-09T06:49:57.557 回答
1

线程在完成工作或您完成工作之前不会死亡interrupt

于 2012-06-09T06:51:29.257 回答
1

线程在退出其 run() 方法时将终止,因此当组件通过 remove() 方法从其父级中删除时,该线程将永远不会终止。

于 2012-06-09T07:05:03.080 回答
0

看看 Component.removeNotify。在您的组件中,保留指向线程的指针:

public class MyPanel extends JPanel {
   private Thread thread = ...;

   public void removeNotify() {
      super.removeNotify();
      thread.interrupt();
   }
}

当awt 决定删除组件的本机对等点(即支持awt 组件的windows 或linux 组件)时,该方法由它自己调用。根据javadoc:

通过销毁本机屏幕资源使该组件无法显示。此方法由工具包内部调用,不应由程序直接调用。覆盖此方法的代码应调用 super.removeNotify 作为覆盖方法的第一行。

于 2012-06-10T01:22:01.020 回答