到目前为止,我将我的应用程序用作独立产品。因此,当用户按下“停止”按钮时,我调用了System.exit(0);
,这很好。
现在我的应用程序将从另一个程序调用(以编程方式)。所以,我担心System.exit(0);
不仅会杀死我的程序,还会杀死启动我程序的外部软件。
那么,如果收到来自外部软件的相应请求,关闭我的应用程序的正确方法是什么?我的应用程序是GUI应用程序。所以,我想关闭窗口,但我也想关闭我的程序执行的所有进程。
增加:
更具体地说,我想关闭程序启动的所有线程。我的程序没有启动任何操作系统进程或任何其他程序。
答案 0 :(得分:2)
如果您启动的线程仍在处理,则调用System.exit(0)将导致它们被杀死。在某些情况下,这可能会使您的应用程序处于不一致状态。想象一下,该线程正在保存一个文件。
在调用System.exit之前,你应该确保你的线程都“满意”。
对于长时间运行的线程,您可以使用的一种技术是中毒。为此,你向线程发送一条消息,告诉他们现在应该优雅地死掉 - 即一条信息。一旦它们全部死亡,可以安全地调用System.exit(0)来终止Swing事件处理线程。
有许多不同的实现中毒的方法,您可以设置一个全局标志变量,线程检查它们是否已被中毒,或者您可以使用Java 5线程库。以这个Javadoc为例,您将找到对此技术的引用:
http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/BlockingQueue.html
答案 1 :(得分:0)
只要您的程序没有与其他人共享应用程序服务器,通过调用System.exit(0)
来关闭VM会终止所有线程。
来自Javadoc System.exit终止当前运行的Java虚拟机)
编辑: 如果您想在关机前执行一些清理代码,http://java.sun.com/j2se/1.4.2/docs/guide/lang/hook-design.html
答案 2 :(得分:0)
不幸的是,有一个“一刀切”的答案是System.exit的直接替代品。
您通常需要设置某种标志,向您的所有线程发出信号表明是时候退出,并确保他们定期检查此标志。这将使他们优雅地清理而不会突然停止,并且还确保效果仅限于您自己的组件。在这种情况下,应用程序的主线程也会观察标志,等待所有“worker”类型的线程完成,然后一直向上返回堆栈,直到达到应用程序的入口点。
这个问题与已弃用的Thread.stop
(等)方法并没有太大的不同,特别是关于用更尊重的东西替换System.exit。在这种情况下,why is Thread.stop() deprecated page可能是有用的阅读。
抛出异常(一个名为ApplicationStopException
的自定义异常)来展开主线程的堆栈并不是一个坏主意;这可以防止您不得不在代码中处理特殊逻辑,而是让“消息”传播到更高级别,他们可以采取任何行动来优雅地退出程序。
答案 3 :(得分:0)
我建议你做标记来停止线程,以便线程知道什么时候必须停止。对于GUI和窗口,您可以调用frame.dispose()。
对于System.exit(),我认为它不会影响调用者,你可能会尝试看看真正的效果是什么,但正如其他人已经建议的那样,不要直接调用它,只需让线程停止本身