优雅地退出应用程序?
我有一个具有明确定义的 Try/Catch/Finally 链的应用程序,它在正常情况下退出并执行 finally 块就好了,但是当有人过早地在 GUI 中点击红色 X 时,程序完全存在(代码 = 0) 并且不会调用主线程的 finally 块.
I have an application with a well defined Try/Catch/Finally chain that exits and executes the finally block just fine under normal conditions, however when someone prematurely hits the red X in the GUI, the program fully exists (code = 0) and the main thread's finally block isn't called.
事实上,我确实希望程序在单击红色 X 时退出,但我不希望跳过 finally{} 块!我在 GUI 中手动放入了 finally 块中最重要的部分,但我真的不想这样做,因为我希望 GUI 与实际程序分离:
In fact, I do want the program to exit upon a click of the red-X, but what I do not want is a skipping of the finally{} block! I sort of put in the most important part of the finally block manually in the GUI but I really do not want to do it this way since I want the GUI decoupled from the actual program:
class GUI { // ...
...
mainFrame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent evt) {
try {
processObject.getIndicatorFileStream().close();
} catch (Exception ignore) {}
System.exit(0);
}
});
...
}
但我更喜欢这样的电话:
But I'd prefer to just have a call like this:
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
并确保在退出后从每个线程调用所有 finally{} 块.
And make sure that all the finally{} blocks get called from each thread after the Exit.
我知道这实际上是意料之中的.如果应用程序从一个单独的线程(比如 GUI 线程)关闭,那么主线程将停止在其轨道上.
I know this is actually expected. If the application is closed from a separate thread (say the GUI thread) then the main thread will just stop in its tracks.
简而言之——我如何确保 System.exit(0) 或 JFrame.EXIT_ON_CLOSE 仍会导致每个线程的 finally 块执行?
推荐答案
如果您没有其他设计更改选择,那么您可能需要一个 JVM 关闭挂钩,在调用 System.exit
时可以添加它来运行一段代码.
If you have no other design change choices then what you may need is a JVM shutdown hook, which can be added to run a piece of code when System.exit
is called.
Shutdown Hooks 是一种特殊的结构,允许开发人员插入在JVM关闭时要执行的一段代码中.这在我们需要进行特殊清理的情况下派上用场虚拟机关闭时的操作.
Shutdown Hooks are a special construct that allow developers to plug in a piece of code to be executed when the JVM is shutting down. This comes in handy in cases where we need to do special clean up operations in case the VM is shutting down.
您可以按此处所述添加关闭挂钩:
You can add a shutdown hook as mentioned here:
Runtime.getRuntime().addShutdownHook(Thread)
在此处阅读有关关闭挂钩的更多信息:
Read more about shutdown hooks here:
http://java.dzone.com/articles/know-jvm-series-2-关机
注意事项:
我们必须记住的是,不能保证关机挂钩将始终运行.如果 JVM 由于某些内部错误而崩溃,那么它可能会崩溃而没有机会执行单个操作说明.此外,如果操作系统发出 SIGKILL(http://en.wikipedia.org/wiki/SIGKILL) 信号(在 Unix/Linux 中为 kill -9)或 TerminateProcess (Windows),则应用程序需要立即终止,甚至不等待任何清理活动.除了上述之外,还可以终止JVM 不允许关闭挂钩通过调用运行Runime.halt() 方法.
We must keep in mind is that it is not guaranteed that shutdown hooks will always run. If the JVM crashes due to some internal error, then it might crash down without having a chance to execute a single instruction. Also, if the O/S gives a SIGKILL (http://en.wikipedia.org/wiki/SIGKILL) signal (kill -9 in Unix/Linux) or TerminateProcess (Windows), then the application is required to terminate immediately without doing even waiting for any cleanup activities. In addition to the above, it is also possible to terminate the JVM without allowing the shutdown hooks to run by calling Runime.halt() method.
相关文章