Occasional InterruptedException when quitting a Swing application

前端 未结 17 1122
心在旅途
心在旅途 2020-12-05 04:55

I recently updated my computer to a more powerful one, with a quad-core hyperthreading processor (i7), thus plenty of real concurrency available. Now I\'m occasionally

相关标签:
17条回答
  • I think i have found where the bug comes from !

    When you have a basic java application with an Exit submenu into a File menu... There is a shortcut to activate the exit Action...This shortcut must makes a circular link or something like that...

    There is the solutions :

    First of all this is optional to get all clear: Implements this Interface "WindowListener" from your main window.

    At the construction of this main window do this :

    JFrame frame=this.getFrame();
    if(frame!=null)
    {
       Window[] windows=frame.getWindows();
       for(Window window : windows)
       window.addWindowListener(this);
    }
    

    implements the functions from the interface :

    public void windowOpened(WindowEvent e) {}
    
    public void windowClosing(WindowEvent e) {
        JFrame frame=this.getFrame();
        if(frame!=null)
        {
            Window[] windows=frame.getOwnedWindows();
            for(Window window : windows)
            {
                window.removeWindowListener(this);
                window.dispose();
            }
        }
        //clear();
        System.gc();
    }
    
    public void windowClosed(WindowEvent e) {}
    public void windowIconified(WindowEvent e) {}
    public void windowDeiconified(WindowEvent e) {}
    public void windowActivated(WindowEvent e) {}
    public void windowDeactivated(WindowEvent e) {}
    

    After that you'll have to be careful about yours shortcuts ! You 'll have to remove the Action from the Exit Menu in order to manage it with an actionPerformed :

    private void exitMenuItemActionPerformed(java.awt.event.ActionEvent evt) {
        //this.clear();
        svExitMenuItem.removeActionListener(null);//this call removes the end error from this way to exit.
        javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance(etscampide.ETScampIDEApp.class).getContext().getActionMap(ETScampIDEView.class, this);
        actionMap.get("quit").actionPerformed(null);//null to avoid end error too
    }
    

    I don't explain why but it works for me... I think that there is a kind of circular references... Hope to help you. See ya.

    0 讨论(0)
  • 2020-12-05 05:12

    I just ran into this error using databases. The problem was that the connection to the database was not closed. I solved this by using the following code :

    Runtime.getRuntime().addShutdownHook(new Thread() {
            public void run() {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        });
    

    Just throwing this out there for other people...

    0 讨论(0)
  • 2020-12-05 05:13

    This seems to be a bug resolved in Java 1.7.

    Configured my Eclipse to run in jdk 1.7 and the error went away.

    Yoav

    0 讨论(0)
  • 2020-12-05 05:14

    If you are using swing application then first call System.gc() and then call dispose() method. I think it will work fine.. I also use this.

    Would like to up-vote this but I need more rep. This solution worked for me although I cannot find the explanation why and my co-worker also says it makes no sense.

    I have 1.7 and a swing app that I have created, it reads in a file, rearranges the contents and then outputs to a file. has a run and quit button. uses preferences API, writer, reader, and a few other things. Upon opening and closing the app (without System.gc()) immediately only two times successively will return this same Exception as stated above. but with System.gc() right before dispose() I cannot get the Exception to throw again.

    0 讨论(0)
  • 2020-12-05 05:17

    It sounds like you have a thread running which hasn't terminated when you quit. Notably, the thread is wait()ing, and that method throws an interrupted exception if you try to stop the thread while it's running. I always set background threads to run as Daemons, which might help as well.

    I would do the following in your JFrame:

    myJFrame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
    addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent we) {
        // Some pieces of code to instruct any running threads, possibly including
        // this one, to break out of their loops
    
        // Use this instead of System.exit(0) - as long as other threads are daemons,
        // and you dispose of all windows, the JVM should terminate.
        dispose();
      }
    });
    

    By manually breaking out of the loop, you allow the wait method to terminate (hopefully you're not waiting terribly long, are you? If you are, you might want to re-examine how you're utilizing your threads) and then get to a point in your code where it's safe to break - safe because you coded it to do so - and then the thread will terminate, letting the application terminate just fine.

    Update Perhaps you are using the event dispatch thread inappropriately somewhere, and it's waiting/still working for you when you try to exit? The dispatcher thread should be doing as little work as possible, and should be passing anything complex off to another thread as quickly as it can. I'll admit I'm stabbing around in the dark a little bit, but I'm inclined to think it's not a bug, especially considering that you started noticing it on a more powerful machine - which to me screams "Race Condition!" not Java bug.

    0 讨论(0)
  • 2020-12-05 05:17

    I had the same problem, and found that I just had a Frame hiding in the background (I had it's visibility set to false). If I made sure to call .dispose() on my hidden frame and then .dispose() on my mainFrame I had no need to call System.exit(0), the application just cleaned itself up and shutdown. My code is Scala, but the idea is the same.

    def top = new MainFrame {
    
       import javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE
       peer.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE)
       override def closeOperation() { endExecution; PreviewFrame.dispose(); this.dispose(); }
    }
    
    0 讨论(0)
提交回复
热议问题