[英]Stop ALL Awt/Swing threads and monitors and stuff so that just the main thread is left
I have the following 我有以下内容
public static void main(String[] args) {
boolean running = true;
boolean foo= false;
while(running)
{
doSomeTask(); // might set foo true
if(foo) {
//This call waits/blocks until gui is done working.
fireUpSwingGui(); //does work...
foo=false;
godModeReleaseGUIandALLResourcesOnlyWantMainThreadLeft();
}
}
}
Hope that godModeReleaseGUIandALLResourcesOnlyWantMainThreadLeft()
says it all. 希望
godModeReleaseGUIandALLResourcesOnlyWantMainThreadLeft()
说明一切。
Bear in mind that we might fire up the gui again at a later stage when foo
becomes true
again somewhere inside doSomeTask()
. 请记住,当
foo
在doSomeTask()
内部再次变为true
时,我们可能会在稍后阶段再次启动gui。
Take a look at AWT Threading Issues which explains the criteria for an AWT application to exit. 看看AWT线程问题 ,它解释了退出AWT应用程序的标准。 The part you want to focus on is the following:
您要关注的部分如下:
Therefore, a stand-alone AWT application that wishes to exit cleanly without calling System.exit must:
因此,希望在不调用System.exit的情况下干净地退出的独立AWT应用程序必须:
- Make sure that all AWT or Swing components are made undisplayable when the application finishes.
确保在应用程序完成时使所有AWT或Swing组件无法显示。 This can be done by calling Window.dispose on all top-level Windows.
这可以通过在所有顶级Windows上调用Window.dispose来完成。 See Frame.getFrames .
请参见Frame.getFrames 。
- Make sure that no method of AWT event listeners registered by the application with any AWT or Swing component can run into an infinite loop or hang indefinitely.
确保应用程序使用任何AWT或Swing组件注册的AWT事件侦听器的任何方法都无法运行到无限循环或无限期挂起。 For example, an AWT listener method triggered by some AWT event can post a new AWT event of the same type to the EventQueue.
例如,由某些AWT事件触发的AWT侦听器方法可以将相同类型的新AWT事件发布到EventQueue。 The argument is that methods of AWT event listeners are typically executed on helper threads.
参数是AWT事件侦听器的方法通常在辅助线程上执行。
A quick sample app to demonstrate... 一个快速示例应用程序来演示......
import java.awt.Frame;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
public class CloseAWT
{
private static boolean running = true;
private static int response = -1;
public static void main(String[] args)
{
boolean showSwing = true;
boolean checkFrames = true;
while (running)
{
if (showSwing)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
response = JOptionPane.showConfirmDialog(null, "Hello World?");
}
});
showSwing = false;
}
else
{
if (response >= 0 && checkFrames)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
// topFrame.dispose();
Frame[] frames = Frame.getFrames();
System.out.printf("frames.length=%d\n", frames.length);
}
});
checkFrames = false;
}
}
}
}
}
To confirm the behavior was as expected, I ran this in JProfiler. 为了确认行为符合预期,我在JProfiler中运行了这个。 After clicking 'yes' to dismiss the confirmation dialog, the 'AWT-EventQueue-0' thread was marked as dead.
单击“是”以关闭确认对话框后,'AWT-EventQueue-0'线程被标记为已死。 The only threads alive after this were the 'main' and the thread which listens for Ctrl-Break.
在此之后唯一活着的线程是'main'和侦听Ctrl-Break的线程。
I highly recommend using something like JProfiler , YourKit , JProbe or one of the free profilers to make sure you've properly released all the components and removed all the listeners. 我强烈建议使用JProfiler , YourKit , JProbe或其中一个免费的分析器,以确保您已正确释放所有组件并删除所有侦听器。
One final thought... You might want to consider spawning your GUI as a separate process and using some sort of IPC to pass information between your daemon process and GUI. 最后一个想法......您可能想要考虑将GUI作为一个单独的进程生成,并使用某种IPC在您的守护进程和GUI之间传递信息。 Although this incurs the additional overhead of an extra process and the IPC, it would give you a greater assurance that your GUI is completely cleaned up when it is no longer needed.
虽然这会产生额外进程和IPC的额外开销,但它可以让您更好地确保在不再需要GUI时完全清理它。
Assuming you're opening JFrame
isntances, why don't you just store them in a collection and inside godModeReleaseGUIandALLResourcesOnlyWantMainThreadLeft()
you iterate over them ans call setVisible(false);
假设您正在打开
JFrame
isntances,为什么不将它们存储在一个集合中,并在godModeReleaseGUIandALLResourcesOnlyWantMainThreadLeft()
迭代它们并调用setVisible(false);
I'm not sure whether you actually can stop the AWT event queue that drives the gui. 我不确定你是否真的可以停止驱动gui的AWT事件队列。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.