使用JVM怎么处理未捕获的异常

发布时间:2021-05-18 17:55:48 作者:Leah
来源:亿速云 阅读:203

使用JVM怎么处理未捕获的异常?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

什么是未捕获异常

未捕获异常指的是我们在方法体中没有使用try-catch捕获的异常,比如下面的例子

private static void testUncaughtException(String arg) {
 try {
 System.out.println(1 / arg.length());
 } catch (ArithmeticException e) {
 e.printStackTrace();
 }
}

上面的代码很有可能发生如下情况

对于上面的问题,我们不难发现

UncaughtExceptionHandler 是什么

ThreadGroup 是什么

未捕获异常处理者 设置指南

使用JVM怎么处理未捕获的异常

线程发生了未捕获异常,JVM怎么处理

分发Throwable实例

当线程A中出现了未捕获异常时,JVM会调用线程A的dispatchUncaughtException(Throwable)方法

/**
 * Dispatch an uncaught exception to the handler. This method is
 * intended to be called only by the JVM.
 */
private void dispatchUncaughtException(Throwable e) {
 getUncaughtExceptionHandler().uncaughtException(this, e);
}

获取未捕获异常处理者

每个线程会有一个变量(uncaughtExceptionHandler)来保存未捕获异常的处理者

在线程需要确定Throwable分发目标的处理者时,优先获取当前线程中uncaughtExceptionHandler变量

如果出问题线程的uncaughtExceptionHandler为null(即没有显式设置异常处理者),则使用自己所在的ThreadGroup来作为未捕获异常处理者。

/**
 * Returns the handler invoked when this thread abruptly terminates
 * due to an uncaught exception. If this thread has not had an
 * uncaught exception handler explicitly set then this thread's
 * <tt>ThreadGroup</tt> object is returned, unless this thread
 * has terminated, in which case <tt>null</tt> is returned.
 * @since 1.5
 * @return the uncaught exception handler for this thread
 */
public UncaughtExceptionHandler getUncaughtExceptionHandler() {
 return uncaughtExceptionHandler != null ?
 uncaughtExceptionHandler : group;
}

如果Throwable分发给ThreadGroup

/**
 * Called by the Java Virtual Machine when a thread in this
 * thread group stops because of an uncaught exception, and the thread
 * does not have a specific {@link Thread.UncaughtExceptionHandler}
 * installed.
 * <p>
 * The <code>uncaughtException</code> method of
 * <code>ThreadGroup</code> does the following:
 * <ul>
 * <li>If this thread group has a parent thread group, the
 * <code>uncaughtException</code> method of that parent is called
 * with the same two arguments.
 * <li>Otherwise, this method checks to see if there is a
 * {@linkplain Thread#getDefaultUncaughtExceptionHandler default
 * uncaught exception handler} installed, and if so, its
 * <code>uncaughtException</code> method is called with the same
 * two arguments.
 * <li>Otherwise, this method determines if the <code>Throwable</code>
 * argument is an instance of {@link ThreadDeath}. If so, nothing
 * special is done. Otherwise, a message containing the
 * thread's name, as returned from the thread's {@link
 * Thread#getName getName} method, and a stack backtrace,
 * using the <code>Throwable</code>'s {@link
 * Throwable#printStackTrace printStackTrace} method, is
 * printed to the {@linkplain System#err standard error stream}.
 * </ul>
 * <p>
 * Applications can override this method in subclasses of
 * <code>ThreadGroup</code> to provide alternative handling of
 * uncaught exceptions.
 *
 * @param t the thread that is about to exit.
 * @param e the uncaught exception.
 * @since JDK1.0
 */
 public void uncaughtException(Thread t, Throwable e) {
 if (parent != null) {
  parent.uncaughtException(t, e);
 } else {
  Thread.UncaughtExceptionHandler ueh =
  Thread.getDefaultUncaughtExceptionHandler();
  if (ueh != null) {
  ueh.uncaughtException(t, e);
  } else if (!(e instanceof ThreadDeath)) {
  System.err.print("Exception in thread \""
     + t.getName() + "\" ");
  e.printStackTrace(System.err);
  }
 }
 }

将上面的处理流程做成图的形式,就是下图所示

使用JVM怎么处理未捕获的异常

注:上述图片来自https://www.javamex.com/tutorials/exceptions/exceptions_uncaught_handler.shtml

Questions

初始的ThreadGroup是什么

上面提到了初始的ThreadGroup没有父ThreadGroup,是主线程所在的ThreadGroup么?

这个问题,我们可以通过这样一段代码验证

private static void dumpThreadGroups() {
 ThreadGroup threadGroup = Thread.currentThread().getThreadGroup();
 while(threadGroup != null) {
 System.out.println("dumpThreadGroups threadGroup=" + threadGroup.getName());
 threadGroup = threadGroup.getParent();
 }
}

执行该方法对应的输出是

dumpThreadGroups threadGroup=main
dumpThreadGroups threadGroup=system

因此我们可以发现,初始的ThreadGroup是一个叫做system的ThreadGroup,而不是main ThreadGroup

setDefaultUncaughtExceptionHandler 设置的一定会被调用到么

这其实是一个很好的问题,答案是不一定会被调用,因为可能存在以下的情况

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注亿速云行业资讯频道,感谢您对亿速云的支持。

推荐阅读:
  1. 未捕获异常,现实程序崩溃闪退
  2. JAVA如何处理未捕获异常

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

jvm

上一篇:如何在MyBatis中执行动态SQL语句

下一篇:activemq怎么在Springboot中使用

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》