Java 引发异常时EDT是否重新启动?

Java 引发异常时EDT是否重新启动?,java,exception,event-dispatch-thread,Java,Exception,Event Dispatch Thread,(下面的示例代码是自包含且可运行的,您可以尝试,它不会使您的系统崩溃:) Tom Hawtin在这里对这个问题发表了评论: 即: EDT不太可能崩溃。EDT调度中抛出的未经检查的异常被捕获、转储,线程继续运行 有人能解释一下这是怎么回事吗(每次你点击“抛出一个未检查的异常”按钮时,都会故意执行除以零的操作): 我得到以下信息(这是我所期望的): 对我来说,这是一个未经检查的例外,对吗 您可以看到,每次触发崩溃时,线程ID都会增加 那么,EDT是在每次抛出未经检查的异常时自动重新启动,还是像Tom

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

Tom Hawtin在这里对这个问题发表了评论:

即:

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

有人能解释一下这是怎么回事吗(每次你点击“抛出一个未检查的异常”按钮时,都会故意执行除以零的操作):

我得到以下信息(这是我所期望的):

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

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

那么,EDT是在每次抛出未经检查的异常时自动重新启动,还是像Tom Hawtin评论的那样,未经检查的异常“被捕获、转储并且线程继续”呢


这是怎么回事?

有趣的问题。我本以为异常被捕获了,线程还在继续,但经过一些研究,我不太确定

我扩展了你的程序

Set<Thread> seenAwtThreads = new HashSet<Thread>();
完整运行方法的实现如下所示:

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

例如,线程ID在我的平台上保持不变。中讨论的净效果是“当至少有一个可显示的组件时,JVM将不会退出。”

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

另一个有趣的注意事项是:不必使用Math.abs(0)来“把戏“让编译器接受它。0/0是一个ok表达式,也会引发异常@他,他,我知道,我知道,我看过那个讨论。。。但如果你写了0/0或1/0,那么人们会问它,它甚至在编译:)哈哈哈。。。好的方面:-)查看
EventDispatchThread.pumpOneEventForFilters
,在当前的实现中,“它很复杂”。显然,不同的实现可能会有所不同。在EDT退出之前,当没有实现windows时,可能总是捕捉到异常。@垃圾神:到目前为止,我只在Debian Linux系统上尝试过:)+1,这个链接非常棒!是 啊我在ubuntu上使用Java6。你在哪个系统上使用垃圾神?@NoozNooz42:虽然Mac OS X保持相同的ID,但我看到你在Ubuntu 10.04上报告的增量。@Trashgood:是的,刚刚在OS X 10.4/Tiger/Java 1.5和OS X 10.6/Snow Leopard/Java 1.6上试用过,两个ID都保持不变。我认为在操作系统X上,在按钮释放之后,按钮没有被正确地重新绘制(在崩溃之后,就像鼠标释放事件丢失一样),而在Linux上,按钮释放被正确地考虑到了(不确定是这样说的)。@NoozNooz42:我在Mac OS X 10.5.8和Ubuntu 10.04上都使用了Java 1.6。eMac的来源和@aioobe显示的相同。@NoozNooz42,不,我想是6。如果您发现它在java 7中发生了更改,请告诉我:-)很抱歉延迟回复。我在MacOSX10.5.8和Ubuntu 10.04上都使用了Java1.6。Mac源与您显示的源相同。
Set<Thread> seenAwtThreads = new HashSet<Thread>();
/*
 * 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.
 */
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);
        }
    }
}