首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >优雅地退出应用程序?

优雅地退出应用程序?
EN

Stack Overflow用户
提问于 2013-07-22 16:40:20
回答 3查看 12.3K关注 0票数 7

我有一个定义良好的Try/Catch/Finally链的应用程序,它在正常情况下退出并执行finally块,但是当某人过早地在GUI中命中红色X时,程序完全存在(代码= 0),并且主线程的最终块不被调用。

事实上,我确实希望程序在单击red-X时退出,但我不想跳过最后的{}块!我在GUI中手动插入了finally块中最重要的部分,但我真的不想这样做,因为我希望GUI与实际程序解耦:

代码语言:javascript
复制
class GUI { // ...
...
mainFrame.addWindowListener(new WindowAdapter() {
  public void windowClosing(WindowEvent evt) {
    try {
      processObject.getIndicatorFileStream().close();
    } catch (Exception ignore) {}
    System.exit(0);
  }
});
...
}

但我宁愿打个这样的电话:

代码语言:javascript
复制
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

并确保在退出后从每个线程调用所有最后的{}块。

我知道这是意料之中的。如果应用程序是从单独的线程(例如GUI线程)关闭的,那么主线程就会停止运行。

简而言之, --如何确保System.exit(0)或JFrame.EXIT_ON_CLOSE仍然会导致每个线程的最后块执行?

EN

回答 3

Stack Overflow用户

发布于 2013-07-22 16:43:01

如果您没有其他的设计更改选择,那么您可能需要一个JVM关机挂钩,当System.exit被调用时,可以添加它来运行一段代码。

关机挂钩是一种特殊的构造,允许开发人员在JVM关闭时插入要执行的代码。在我们需要进行特殊清理操作以防止VM关闭的情况下,这是很有用的。

您可以添加关闭钩子,如下所述:

代码语言:javascript
复制
Runtime.getRuntime().addShutdownHook(Thread)

在这里阅读更多关于关机挂钩的信息:

http://java.dzone.com/articles/know-jvm-series-2-shutdown

警告词:

我们必须记住的是,不能保证关闭钩子将始终运行。如果JVM由于某些内部错误而崩溃,那么它可能会崩溃而没有机会执行一条指令。另外,如果O/S给出了一个SIGKILL (http://en.wikipedia.org/wiki/SIGKILL)信号(Unix/Linux中的TerminateProcess -9 )或TerminateProcess(TerminateProcess),那么应用程序就必须立即终止,而无需等待任何清理活动。除了上述之外,还可以终止JVM,而不允许通过调用Runime.halt()方法运行关机挂钩。

票数 8
EN

Stack Overflow用户

发布于 2013-07-22 17:00:04

如果您碰巧有这样的线程,这些线程可以在任何时候、在它们的循环中的任何点、在它们调用的任何方法内的任何点上合法地停止,我想警告您,您不太可能这样做,那么您可以在程序退出时将它们全部关闭。这将导致在每个线程中抛出异常,finally块将执行。

然而,实现您的目标并使GUI与程序逻辑分离的正确方法是从GUI发出一个“退出”信号,这将触发所有应用程序清理,这是在一个完全不同的类中编写的。如果您有正在运行的线程,那么在每个线程中实现interrupt机制。

实现退出信号的方法有很多。例如,您的业务代码可以为一个特殊事件注册GUI侦听器,这将触发清理。您还可以在await上有一个线程,它只执行CountDownLatch上的任何事情,这将是GUI中的countDown

请不要以任何代价使用关闭钩子。这是可以想象到的最肮脏的机制,只有在所有正常的清理程序都失败时,这才是最后的手段。它永远不会被用作常规关机程序的一部分。

总之,没有清理应用程序关闭的绝好方法。您必须为每个特定的关注点实现特定的机制。

票数 3
EN

Stack Overflow用户

发布于 2017-03-05 11:19:17

使用现代的Java,在所有应用程序窗口上的Window.dispose()可以提供比System.exit(0)更优雅的退出AWT应用程序的可能性,请参见

https://docs.oracle.com/javase/8/docs/api/java/awt/Window.html#dispose--

代码语言:javascript
复制
/** Listens and closes AWT windows.
 * The class is implemented as singleton since only one is needed.
 */
public class ExitListener extends WindowAdapter {

  /** the instance object */
  private static final ExitListener INSTANCE = new ExitListener();

  // hide the constructor
  private ExitListener () {}

  /** retrieve the listener object */
  public static ExitListener getInstance () {
    return INSTANCE;
  }

  @Override
  public void windowClosing ( final WindowEvent e ) {
    e.getWindow().dispose();
  }
}

用你的窗户

代码语言:javascript
复制
window.addWindowListener( ExitListener.getInstance() );

然而,在不利的环境中要小心,见:

https://docs.oracle.com/javase/8/docs/api/java/awt/doc-files/AWTThreadIssues.html#Autoshutdown

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17792939

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档