java - 是什么阻止程序退出?

标签 java multithreading swing jframe

我是这样写的。

public static void main(String[] args){
    Thread thread = new Thread(() -> {
        while(true){
            try{
                // do something
                Thread.sleep(10);
            }catch(InterruptedException ex){
                System.out.println("ABC");
                break;
            }
        }
    });
    JFrame frame = new JFrame();
    frame.setSize(1280,720);
    frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    frame.addWindowListener(new WindowAdapter(){
        @Override
        public void windowClosed(WindowEvent e){
            thread.interrupt();
        }
    });
    thread.start();
    frame.setVisible(true);
}

当我点击窗口的“关闭”按钮时,
程序花了几秒钟才结束。
是什么阻止程序退出?
以及如何使用JFrame.EXIT_ON_CLOSE 立即关闭程序?

我认为我的线程(while(true) 线程)立即结束
因为在我点击“关闭”按钮后很快就会显示“ABC”。

谢谢。

编辑

没有我的线程也发生了同样的事情。

public static void main(String[] args){
    JFrame frame = new JFrame();
    frame.setSize(1280,720);
    frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    frame.setVisible(true);
}

编辑2

public static void main(String[] args){
    Runtime.getRuntime().addShutdownHook(new Thread(() -> {
        Thread[] threads = new Thread[5];
        Thread.enumerate(threads);
        System.out.println(Arrays.toString(threads));
        System.err.println(LocalDateTime.now() + " SHUTDOWN");
    }
    ));
    JFrame frame = new JFrame();
    frame.setSize(1280,720);
    frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    frame.addWindowListener(new WindowAdapter(){
            @Override
            public void windowClosed(WindowEvent e){
                Thread[] threads = new Thread[5];
                Thread.enumerate(threads);
                System.out.println(Arrays.toString(threads));
                System.err.println(LocalDateTime.now() + " CLOSE");
            }
        });
    frame.setVisible(true);
}  

输出是:

[Thread[AWT-EventQueue-0,6,main], Thread[DestroyJavaVM,5,main], null, null, null]
2016-08-02T19:04:50.465 CLOSE
[Thread[DestroyJavaVM,5,main], Thread[Thread-0,5,main], null, null, null]
2016-08-02T19:04:51.762 SHUTDOWN

最佳答案

虽然通常应谨慎使用 System.exit(),但 Swing documentation明确指出在问题中所示的场景中这是正确的方法:

When the last displayable window within the Java virtual machine (VM) is disposed of, the VM may terminate. Note, however, that there can be a delay before the program exits automatically, and that under some circumstances the program might keep running. It is quicker and safer to explicitly exit the program using System.exit(int).

以下示例未显示关闭操作和关闭 Hook 之间的延迟。删除 System.exit(0) 调用时,大约延迟。可以观察到 1.3 秒:

package com.example.swing;

import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.time.LocalDateTime;

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

public class ExitDelay {
    public static void main(String[] args){

        Runtime.getRuntime().addShutdownHook(new Thread(() -> System.err.println(LocalDateTime.now() + " SHUTDOWN") ));

        SwingUtilities.invokeLater(() -> {

            JFrame frame = new JFrame();
            frame.setSize(1280,720);
            frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            frame.addWindowListener(new WindowAdapter(){
                @Override
                public void windowClosed(WindowEvent e){
                    System.err.println(LocalDateTime.now() + " CLOSE");

                    // Do all required cleanup stuff.
                    // check that threads are done, close files, commit transactions etc.
                    // ...

                    System.exit(0);
                }
            });
            frame.setVisible(true);

        });
    }
}

关于java - 是什么阻止程序退出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38716167/

相关文章:

python - 使用 python 和依赖项进行多处理

java - Mule 错误,只有所有者线程可以写入 http 模块仍然发生的消息

c# - 创建一种从另一个线程安全访问控件的方法

java - 是否可以读取.txt文件的文件名并将其写入二叉树?

java - JDialog标题的字体大小

java - 使用 Principal REST hibernate @OneToOne 映射

java - spring mvc Controller 类不工作

从 IDE Netbeans 运行 Java GUI 程序

java - 如何在java中的嵌套循环中中断if语句

java - SQLite异常,数据库已关闭