簡體   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