抛出异常时EDT是否重启?

时间:2010-06-11 06:56:38

标签: java exception event-dispatch-thread

(下面的示例代码是自包含且可运行的,您可以尝试它,它不会使系统崩溃:)

Tom Hawtin在这里评论了这个问题:Why do people run Java GUI's on the Event Queue

的是:

EDT不太可能崩溃。在EDT调度中抛出的未经检查的异常被捕获,转储并且线程继续。

有人可以解释一下这里发生了什么(每次点击“抛出未经检查的异常”按钮时,会故意执行除零):

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

}

我收到以下消息(这是我期望的):

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

对我来说这是一个未经检查的例外吗?

您可以看到每次触发崩溃时线程ID都会增加。

每次抛出未经检查的异常或未经检查的异常“捕获,转储并且线程继续”就像Tom Hawtin评论的那样,EDT会自动重启吗?

这里发生了什么?

3 个答案:

答案 0 :(得分:5)

有趣的问题。我本以为抓住了异常并且线程继续进行,但经过一些研究我不太确定。

我用

扩展了你的程序
Set<Thread> seenAwtThreads = new HashSet<Thread>();

我收集了所有“看到的”awt线程,每次单击“throw exception”按钮时,set的大小都会增加,这似乎表明在异常的情况下初始化了一个新线程。 / p>

最后,我在run的{​​{1}}实施中找到了此评论:

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

答案 1 :(得分:4)

供参考,“this machinery的特定行为取决于实现。”例如,线程ID在我的平台上保持不变。 AWT Threading Issues中讨论的净效应是“当至少有一个可显示组件时,JVM不会退出。”

答案 2 :(得分:0)

在事件调度线程上设置了一个默认的UncaughtExceptionHandler,它将异常打印到System.out,然后在线程中继续。