线程管理(八)在线程里处理不受控制的异常

简介:

在线程里处理不受控制的异常

Java里有2种异常:

  • 检查异常(Checked exceptions): 这些异常必须强制捕获它们或在一个方法里的throws子句中。 例如, IOException 或者ClassNotFoundException。
  • 未检查异常(Unchecked exceptions): 这些异常不用强制捕获它们。例如, NumberFormatException。

在一个线程 对象的 run() 方法里抛出一个检查异常,我们必须捕获并处理他们。因为 run() 方法不接受 throws 子句。当一个非检查异常被抛出,默认的行为是在控制台写下stack trace并退出程序。

幸运的是, Java 提供我们一种机制可以捕获和处理线程对象抛出的未检测异常来避免程序终结。

在这个指南中, 我们将用实例来学习这个机制。

准备

指南中的例子是使用Eclipse IDE 来实现的。如果你使用Eclipse 或者其他的IDE,例如NetBeans, 打开并创建一个新的java项目。

怎么做呢

按照这些步骤来实现下面的例子:

1.   首先, 我们必须实现一个类来处理非检查异常。这个类必须实现 UncaughtExceptionHandler 接口并实现在接口内已声明的uncaughtException() 方法。在这里,命名此类为 ExceptionHandler  ,并让此方法里写有关于抛出异常的线程信息和异常信息,按照下面的代码:


01 public class ExceptionHandler implements UncaughtExceptionHandler
02 {
03     public void uncaughtException(Thread t, Throwable e) {
04       System.out.printf("An exception has been captured\n");
05       System.out.printf("Thread: %s\n",t.getId());
06       System.out.printf("Exception: %s: %s\n",e.getClass().getName(),e.getMessage());
07       System.out.printf("Stack Trace: \n");
08       e.printStackTrace(System.out); System.out.printf("Thread status: %s\n",t.getState());
09     }
10 }

2.   现在,实现一个类抛出非检查异常。 命名此类为Task一定要实现 Runnable 接口,实现 run() 方法并刻意出异常, 例如,尝试将 string 值转化成  int 值。


1 public class Task implements Runnable {
2 @Override
3 public void run() {
4 int numero=Integer.parseInt("TTT");
5 }
6 }

3.   现在,实现例子主类。实现 Main类和 main() 方法.


1 public class Main {
2 public static void main(String[] args) {

4.   创建 Task 对象并用线程运行它。使用 setUncaughtExceptionHandler() 方法设置非检查异常 handler 并开始执行线程。


1 Task task=new Task();
2 Thread thread=new Thread(task);
3 thread.setUncaughtExceptionHandler(new ExceptionHandler());
4 thread.start();
5 }
6 }

5.   运行例子并查看结果。

它是怎么工作的

在下面的裁图,你可以发现例子的运行结果。异常被handler捕捉,并在操控台写下了有关异常和抛出它的线程的信息。请看下图:

当在一个线程里抛出一个异常,但是这个异常没有被捕获(这肯定是非检查异常), JVM 检查线程的相关方法是否有设置一个未捕捉异常的处理者 。如果有,JVM 使用Thread 对象和 Exception 作为参数调用此方法 。

如果线程没有捕捉未捕获异常的处理者, 那么 JVM会把异常的 stack trace 写入操控台并结束任务。

更多

The Thread 类有其他相关方法可以处理未捕获的异常。静态方法 setDefaultUncaughtExceptionHandler() 为应用里的所有线程对象建立异常 handler 。

当一个未捕捉的异常在线程里被抛出,JVM会寻找此异常的3种可能潜在的处理者(handler)。

首先, 它寻找这个未捕捉的线程对象的异常handle,如我们在在这个指南中学习的。如果这个handle 不存在,那么JVM会在线程对象的ThreadGroup里寻找非捕捉异常的handler,如在处理线程组内的不受控制异常里介绍的那样。如果此方法不存在,正如我们在这个指南中学习的,那么 JVM 会寻找默认非捕捉异常handle。

如果没有一个handler存在, 那么 JVM会把异常的 stack trace 写入操控台并结束任务。

参见

  • 第一章:线程管理:在线程组里处理不受控制的异常
目录
相关文章
|
2月前
|
安全 Java 开发者
丢失的8小时去哪里了?SimpleDateFormat线程不安全,多线程初始化异常解决方案
丢失的8小时去哪里了?SimpleDateFormat线程不安全,多线程初始化异常解决方案
36 0
|
1月前
|
存储 开发框架 安全
【C++ 线程】深入理解C++线程管理:从对象生命周期到线程安全
【C++ 线程】深入理解C++线程管理:从对象生命周期到线程安全
86 0
线程池内运行的线程抛异常,线程池会怎么办
线程池内运行的线程抛异常,线程池会怎么办
|
8月前
|
Java
Java多线程:捕获线程异常
你处理过多线程中的异常吗?如何捕获多线程中发生的异常?捕获子线程的异常与捕获当前线程的异常一样简单吗?
|
11月前
|
存储 Java
高并发编程-捕获线程运行时的异常 + 获取调用链
高并发编程-捕获线程运行时的异常 + 获取调用链
67 0
|
11月前
|
SQL 关系型数据库 MySQL
MySQL主主SQL线程异常修复大作战,一失足成千古恨啊!
MySQL主主SQL线程异常修复大作战,一失足成千古恨啊!
318 0
|
11月前
|
SQL 监控 关系型数据库
MySQL主从复制“死掉”!引发Slave库SQL线程异常的一次“血案”追踪
MySQL主从复制“死掉”!引发Slave库SQL线程异常的一次“血案”追踪
826 0
|
12月前
|
JavaScript 小程序 Java
线程池中线程抛了异常,该如何处理?
线程池中线程抛了异常,该如何处理?
如何处理JDK线程池内线程执行异常?讲得这么通俗,别还搞不懂
本篇 《如何处理 JDK 线程池内线程执行异常》 这篇文章适合哪些小伙伴阅读呢? 适合工作中使用线程池却不知异常的处理流程,以及不知如何正确处理抛出的异常
|
监控 NoSQL 算法
linux下定位异常消耗的线程实战分析
linux下定位异常消耗的线程实战分析
159 0
linux下定位异常消耗的线程实战分析

热门文章

最新文章

相关实验场景

更多