抛出异常时EDT是否重新启动?
(下面的示例代码是独立且可运行的,您可以尝试一下,它不会使您的系统崩溃:)
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);
}
}
我收到以下消息(这是我所期望的):
Exception in thread "AWT-EventQueue-0" java.lang.ArithmeticException: / by zero
对我来说,这是一个未经检查的异常,对吧?
您可以看到,每次触发崩溃时,线程 ID 都会递增。
那么,每次抛出未经检查的异常时,EDT 都会自动重新启动吗?还是像 Tom Hawtin 评论的那样,未经检查的异常“被捕获、转储,线程继续运行”?
这是怎么回事?
(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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
有趣的问题。我本以为异常被捕获并且线程继续,但经过一些研究后我不太确定。
我用一个收集了所有“看到的”awt 线程的程序扩展了你的程序
,每次单击“抛出异常”按钮时,集合的大小都会增加,这似乎表明在出现异常情况时会初始化一个新线程。例外。
最后我在
EventDispatchThread
的run
实现中找到了这样的注释:完整的run方法的实现如下所示:
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
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 ofEventDispatchThread
:The implementation of the complete run method looks like:
作为参考,“此机器的特定行为 取决于实现。”例如,线程 ID 在我的平台上保持不变。最终效果,在 AWT 线程问题 是“当至少有一个可显示组件时,JVM 将不会退出”。
For reference, "The particular behavior of this machinery is implementation-dependent." For example, the thread ID remains unchanged on my platform. The net effect, discussed in AWT Threading Issues, is that "the JVM will not exit while there is at least one displayable component."
有一个默认的 UncaughtExceptionHandler在事件调度线程上设置,它将异常打印到 System.out,然后在线程中继续。
There is an default UncaughtExceptionHandler set on the Event Dispatch Thread, which prints the Exception to System.out and then continues in the Thread.