Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

(the example code below is self-contained and runnable, you can try it, it won't crash your system :)

Tom Hawtin commented on the question here: Why do people run Java GUI's on the Event Queue

that:

It's unlikely that the EDT would crash. Unchecked exceptions thrown in EDT dispatch are caught, dumped and the thread goes on.

Can someone explain me what is going on here (every time you click on the "throw an unchecked exception" button, a divide by zero is performed, on purpose):

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class CrashEDT extends JFrame {

    public static void main(String[] args) {
        final CrashEDT frame = new CrashEDT();
        frame.addWindowListener(new WindowAdapter() {
            public void windowClosing( WindowEvent e) {
                System.exit(0);
            }
        });
        final JButton jb = new JButton( "throw an unchecked exception" );
        jb.addActionListener( new ActionListener() {
            public void actionPerformed( ActionEvent e ) {
                System.out.println( "Thread ID:" + Thread.currentThread().getId() );
                System.out.println( 0 / Math.abs(0) );
            }
        } );
        frame.add( jb );
        frame.setSize(300, 150);
        frame.setVisible(true);
    }

}

I get the following message (which is what I'd expect):

Exception in thread "AWT-EventQueue-0" java.lang.ArithmeticException: / by zero

and to me this is an unchecked exception right?

You can see that the thread ID is getting incremented every time you trigger the crash.

So is the EDT automatically restarted every time an unchecked exception is thrown or are unchecked exceptions "caught, dumped and the thread goes on" like Tom Hawtin commented?

What is going on here?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
300 views
Welcome To Ask or Share your Answers For Others

1 Answer

Interesting question. I would have thought that the exceptions were caught and that the thread went on, but after some research I'm not so sure.

I extended your program with a

Set<Thread> seenAwtThreads = new HashSet<Thread>();

in which I collected all "seen" awt threads, and the size of the set increases each time I click the "throw exception"-button, which seems to suggest that a new thread is initialized in case of an exception.

Finally I found this comment in the run implementation of EventDispatchThread:

/*
 * Event dispatch thread dies in case of an uncaught exception. 
 * A new event dispatch thread for this queue will be started
 * only if a new event is posted to it. In case if no more
 * events are posted after this thread died all events that 
 * currently are in the queue will never be dispatched.
 */

The implementation of the complete run method looks like:

public void run() {
    try {
        pumpEvents(new Conditional() {
            public boolean evaluate() {
                return true;
            }
        });     
    } finally {
        /*
         * This synchronized block is to secure that the event dispatch 
         * thread won't die in the middle of posting a new event to the
         * associated event queue. It is important because we notify
         * that the event dispatch thread is busy after posting a new event
         * to its queue, so the EventQueue.dispatchThread reference must
         * be valid at that point.
         */
        synchronized (theQueue) {
            if (theQueue.getDispatchThread() == this) {
                theQueue.detachDispatchThread();
            }
            /*
             * Event dispatch thread dies in case of an uncaught exception. 
             * A new event dispatch thread for this queue will be started
             * only if a new event is posted to it. In case if no more
             * events are posted after this thread died all events that 
             * currently are in the queue will never be dispatched.
             */
            /*
             * Fix for 4648733. Check both the associated java event
             * queue and the PostEventQueue.
             */
            if (theQueue.peekEvent() != null || 
                !SunToolkit.isPostEventQueueEmpty()) { 
                theQueue.initDispatchThread();
            }
            AWTAutoShutdown.getInstance().notifyThreadFree(this);
        }
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...