典型的Swing应用程序在开始时启动EDT,当最后一个窗口关闭时,Application基本上使用隐式或显式的System.exit停止。
但是我的小应用程序实际上是一个对Swing一无所知的框架的插件。我的插件将在调用时显示一个对话框,以便从用户那里获得一些输入并在之后退出,但框架将/必须继续运行。所以我不能打电话 System.exit
。
但如果我不这样做,EDT将继续运行,一旦框架完成,EDT仍将运行并运行并运行...
所以我想在不杀死应用程序的情况下杀死EDT。我怎么做?
典型的Swing应用程序在开始时启动EDT,当最后一个窗口关闭时,Application基本上使用隐式或显式的System.exit停止。
但是我的小应用程序实际上是一个对Swing一无所知的框架的插件。我的插件将在调用时显示一个对话框,以便从用户那里获得一些输入并在之后退出,但框架将/必须继续运行。所以我不能打电话 System.exit
。
但如果我不这样做,EDT将继续运行,一旦框架完成,EDT仍将运行并运行并运行...
所以我想在不杀死应用程序的情况下杀死EDT。我怎么做?
Oracle / Sun的以下文档阐述了该问题: AWT线程问题
[...]
在1.4之前,辅助线程从未终止。
从1.4开始,由于4030718的修复,行为已经改变。使用当前实现,AWT终止其所有帮助程序线程,允许应用程序在满足以下三个条件时干净地退出:
- 没有可显示的AWT或Swing组件。
- 本机事件队列中没有本机事件。
- java EventQueues中没有AWT事件。
因此,希望在不调用System.exit的情况下干净地退出的独立AWT应用程序必须:
- 确保应用程序完成后,所有AWT或Swing组件都不可显示。这可以通过在所有顶级Windows上调用Window.dispose来完成。请参见Frame.getFrames。 ...
- 确保应用程序使用任何AWT或Swing组件注册的AWT事件侦听器的任何方法都无法运行到无限循环或无限期挂起。例如,由某些AWT事件触发的AWT侦听器方法可以向EventQueue发布相同类型的新AWT事件。参数是AWT事件侦听器的方法通常在辅助线程上执行。
[...]
Oracle / Sun的以下文档阐述了该问题: AWT线程问题
[...]
在1.4之前,辅助线程从未终止。
从1.4开始,由于4030718的修复,行为已经改变。使用当前实现,AWT终止其所有帮助程序线程,允许应用程序在满足以下三个条件时干净地退出:
- 没有可显示的AWT或Swing组件。
- 本机事件队列中没有本机事件。
- java EventQueues中没有AWT事件。
因此,希望在不调用System.exit的情况下干净地退出的独立AWT应用程序必须:
- 确保应用程序完成后,所有AWT或Swing组件都不可显示。这可以通过在所有顶级Windows上调用Window.dispose来完成。请参见Frame.getFrames。 ...
- 确保应用程序使用任何AWT或Swing组件注册的AWT事件侦听器的任何方法都无法运行到无限循环或无限期挂起。例如,由某些AWT事件触发的AWT侦听器方法可以向EventQueue发布相同类型的新AWT事件。参数是AWT事件侦听器的方法通常在辅助线程上执行。
[...]
可能存在一些隐藏的窗口(例如,使用显示的对话框) JOptionPane.showMessageDialog(…)
已经关闭)防止Swing退出。你可以用它来检查
Stream.of(Window.getWindows()).forEach(System.out::println);
如果你不再需要它们,你可以轻松摆脱它们:
Stream.of(Window.getWindows()).forEach(Window::dispose);
然后应该停止事件调度线程。