为什么在创建JFrame对象并将其设置为可见之后,程序将不会结束执行?

wec*_*ing 3 java concurrency swing multithreading

我的程序看起来像这样:

import java.awt.*;
import javax.swing.*;

public class Main {
    public static void main(String[] args) {
        JFrame jf = new JFrame();
        jf.setSize(new Dimension(200, 200));
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.setVisible(true);
    }
}
Run Code Online (Sandbox Code Playgroud)

我很困惑为什么在JVM从main()退出后,我的程序不会立即结束?我注意到如果我删除行"jf.setVisible(true);",它将结束.

它是通过垃圾收集或类析构函数等技术实现的吗?我很感兴趣,如果我想写类似的东西,我怎么能这样做.

Hov*_*els 9

原因是当您在JFrame上调用setVisible(true)时,在后台启动非守护程序线程,并且在所有非守护程序线程终止之前JVM不会退出.

有关AWT/Swing线程问题的更多信息,请查看此处.
它指出:

"至少有一个活动的非守护程序线程,而应用程序中至少有一个可显示的AWT或Swing组件(请参阅Component.isDisplayable)."

虽然这是针对Java 1.5的,但我认为它仍然是有效的信息.

另外,我认为Event Dispatch Thread或EDT不是守护程序线程,因此它是与Swing相关联的另一个驱动它的线程.

编辑1
这表明EDT实际上是一个非守护程序线程:

import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class IsEdtDaemon {
   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
             JFrame frame = new JFrame();
             frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
             frame.setVisible(true);

             System.out.printf("Is the current thread the EDT thread: %b%n",  SwingUtilities.isEventDispatchThread());
             System.out.printf("Is our EDT Thread a daemon thread:    %b%n",  Thread.currentThread().isDaemon());
         }
      });
   }
}
Run Code Online (Sandbox Code Playgroud)

代码的输出是:

当前线程是EDT线程:true
我们的EDT线程是一个守护线程:false