Noo*_*z42 11 java exception event-dispatch-thread
(下面的示例代码是自包含且可运行的,您可以尝试它,它不会崩溃您的系统:)
Tom Hawtin在这里评论了这个问题:为什么人们在事件队列上运行Java GUI
那:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
我得到以下消息(这是我期望的):
Exception in thread "AWT-EventQueue-0" java.lang.ArithmeticException: / by zero
Run Code Online (Sandbox Code Playgroud)
对我来说,这是一个未经检查的例外吗?
您可以看到每次触发崩溃时线程ID都会增加.
每次抛出未经检查的异常时,EDT会自动重启,还是未经检查的异常"捕获,转储和线程继续",就像Tom Hawtin评论的那样?
这里发生了什么?
有趣的问题.我本以为抓住了异常并且线程继续进行,但经过一些研究我不太确定.
我用一个扩展你的程序
Set<Thread> seenAwtThreads = new HashSet<Thread>();
Run Code Online (Sandbox Code Playgroud)
我收集了所有"看到"的awt线程,每次单击"throw exception"按钮时,set的大小都会增加,这似乎表明在异常的情况下初始化了一个新线程.
最后我在run执行中发现了这条评论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.
*/
Run Code Online (Sandbox Code Playgroud)
完整运行方法的实现如下:
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)