什么阻止程序退出?

时间:2016-08-02 09:05:19

标签: 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);
}

EDIT2

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

3 个答案:

答案 0 :(得分:6)

虽然通常应谨慎使用(function() { var elem = document.getElementById("myBar"); var width = 0; var id = setInterval(frame, 50); function frame() { if (width >= document.getElementById("results-percentile-2").innerHTML) { clearInterval(id); } else { width++; elem.style.width = width + '%'; document.getElementById("demo").innerHTML = width * 1 + '%'; } } }()); // End javascript progress bar results // Progress bar javascrip speed (function() { var elem = document.getElementById("myBarspeed"); var width = 0; var id = setInterval(frame, 50); function frame() { if (width >= document.getElementById("results-speed").innerHTML) { clearInterval(id); } else { width++; elem.style.width = width + '%'; document.getElementById("speed").innerHTML = width * 1 + '%'; } } }()); ,但Swing documentation明确指出在问题中显示的方案中它是正确的方法:

  

当Java虚拟机(VM)中的最后一个可显示窗口时   如果丢弃,则VM可以终止。但请注意,可以   在程序自动退出之前是一段延迟,然后是   某些情况下程序可能会继续运行。 它更快   使用System.exit() 明确退出程序更安全。

以下示例未显示关闭操作和关闭挂钩之间的延迟。删除System.exit(int)电话时,延迟时间约为可以观察到1,3秒:

System.exit(0)

答案 1 :(得分:0)

要立即退出程序,您可以使用System.exit(0)

就像那样:

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");
                System.exit(0);
            }
        }
    });
    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);
}

答案 2 :(得分:0)

您使用DISPOSE_ON_CLOSE这是有道理的,因为EXIT_ON_CLOSE将使用System.exit关闭所有活动线程的jvm进程。 JFrame是一个复杂的结构,它使用一些本机调用来为操作系统上的鼠标事件注册回调。所以一个干净的出口需要一些时间。此外,垃圾收集器需要一些时间来检测运行AWT-Thread的{​​{1}}在杀死它之前是否已完成清理。所以我认为1.3秒是可以接受的,因为你的应用程序可以干净利落 但是如果你真的想这样做,你可以强制结束另一个JFrame,它只是连续检查所有正在运行的线程是否已完成工作并且所有Thread都已消失。如果是这样,那就称之为大恶JFrames


System.exit

并添加此结束检查线程

final JFrame frame = new JFrame(); // make your JFrame final
final Thread thread  = new Thread(() ...  // make your Thread final