繁体   English   中英

停止所有Awt / Swing线程和监视器和东西,以便只剩下主线程

[英]Stop ALL Awt/Swing threads and monitors and stuff so that just the main thread is left

我有以下内容

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();
        }
    }
}

希望godModeReleaseGUIandALLResourcesOnlyWantMainThreadLeft()说明一切。

请记住,当foodoSomeTask()内部再次变为true时,我们可能会在稍后阶段再次启动gui。

看看AWT线程问题 ,它解释了退出AWT应用程序的标准。 您要关注的部分如下:

因此,希望在不调用System.exit的情况下干净地退出的独立AWT应用程序必须:

  • 确保在应用程序完成时使所有AWT或Swing组件无法显示。 这可以通过在所有顶级Windows上调用Window.dispose来完成。 请参见Frame.getFrames
  • 确保应用程序使用任何AWT或Swing组件注册的AWT事件侦听器的任何方法都无法运行到无限循环或无限期挂起。 例如,由某些AWT事件触发的AWT侦听器方法可以将相同类型的新AWT事件发布到EventQueue。 参数是AWT事件侦听器的方法通常在辅助线程上执行。

一个快速示例应用程序来演示......

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;
                }
            }
        }
    }
}

为了确认行为符合预期,我在JProfiler中运行了这个。 单击“是”以关闭确认对话框后,'AWT-EventQueue-0'线程被标记为已死。 在此之后唯一活着的线程是'main'和侦听Ctrl-Break的线程。

我强烈建议使用JProfilerYourKitJProbe或其中一个免费的分析器,以确保您已正确释放所有组件并删除所有侦听器。

最后一个想法......您可能想要考虑将GUI作为一个单独的进程生成,并使用某种IPC在您的守护进程和GUI之间传递信息。 虽然这会产生额外进程和IPC的额外开销,但它可以让您更好地确保在不再需要GUI时完全清理它。

假设您正在打开JFrame isntances,为什么不将它们存储在一个集合中,并在godModeReleaseGUIandALLResourcesOnlyWantMainThreadLeft()迭代它们并调用setVisible(false);

我不确定你是否真的可以停止驱动gui的AWT事件队列。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM