在Swing-app中可以从任何线程调用System.exit()
吗? (例如在美国东部时间?)
答案 0 :(得分:6)
如果可以提供帮助,则不应致电System.exit()
。
退出java进程的最佳方法是让所有线程正常退出。这将终止VM。
在您的主JFrame
中,您应该setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
。
然后,您可以致电frame.dispose()
关闭JFrame
并退出EDT。
答案 1 :(得分:5)
由于VM在System.exit()
调用后被终止,我认为这与调用哪个线程没有任何区别。
答案 2 :(得分:3)
你可以从任何一个线程调用它,但使用它有点粗鲁恕我直言。无论正在运行什么,虚拟机都将被终止。
我更喜欢dispose()
或只关闭(拥有setDefaultCloseOperation(DISPOSE_ON_CLOSE)
)任何显示的窗口(JFrame,JDialog,...)。如果只有守护程序线程在运行,则虚拟机将被终止。如果存在一些实时非守护程序线程,则JVM将不会终止,并且线程可以完成其工作
这样做,我总是可以将一个程序中的一部分包含在另一个程序中,而不必担心其中一个程序是否会意外终止另一个程序。
JVM确实需要被“杀死”的情况很少......
答案 3 :(得分:1)
System.exit()
不会终止正在运行的线程,而是终止虚拟机本身。因此可以从任何线程调用它,结果总是相同的,如果VM死掉,线程中所有可能的不一致状态将不会立即存在。
答案 4 :(得分:1)
从您希望的任何线程调用System.exit绝对没有错。让它“正常”退出在实践中不起作用,因为在应用程序退出之前,你会发现应用程序将在GC收集内容时闲逛。 我已经写了很多gui Swing应用程序,并且调用它绝对没有错。这也不是“粗鲁”。这是Java方式。
答案 5 :(得分:0)
有正常终止的EDT线程的Swing规则。
最重要的是确保所有框架都已处理完毕。 不幸的是,如果你使用没有父项的模态对话框,这可能不是那么简单,因为Swing会为这样的对话框创建一个不可见的父框架。
在这种情况下,您必须列出所有框架(您可以使用Frame.getFrames()
)并明确dispose()
。
当然,您必须确保没有Thread
存活(守护进程除外)。一些库甚至JDK中的一些API都会创建非守护程序线程,您必须自己关闭它们。
最后,最重要的是,不调用System.exit()将无法在Java Web Start环境中工作(请查看this SO question以查找更多信息)。
因此,总之,我的建议是实际调用System.exit()
,因为您并不总是知道应用程序将在哪个环境中启动。但我想补充一点:确保从中执行退出的单个点。从任意线程调用它都可以。
答案 6 :(得分:0)
从任何线程调用System.exit都是安全的,但不能从shutdown hook线程调用。我最近不得不调试这种流程https://knotgillcup.blogspot.com/2019/08/systemexit-not-working.html
终止JVM的更为残酷的方法是调用Runtime.halt()方法。