简体   繁体   中英

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.

Bear in mind that we might fire up the gui again at a later stage when foo becomes true again somewhere inside doSomeTask() .

Take a look at AWT Threading Issues which explains the criteria for an AWT application to exit. 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:

  • Make sure that all AWT or Swing components are made undisplayable when the application finishes. This can be done by calling Window.dispose on all top-level Windows. See 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. For example, an AWT listener method triggered by some AWT event can post a new AWT event of the same type to the EventQueue. The argument is that methods of AWT event listeners are typically executed on helper threads.

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. After clicking 'yes' to dismiss the confirmation dialog, the 'AWT-EventQueue-0' thread was marked as dead. The only threads alive after this were the 'main' and the thread which listens for 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.

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. 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.

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

I'm not sure whether you actually can stop the AWT event queue that drives the gui.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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