《Java程序员面试秘笈》—— 1.9 线程中不可控异常的处理

1.9 线程中不可控异常的处理

在Java中有两种异常。

◆ 非运行时异常(Checked Exception):这种异常必须在方法声明的throws语句指定,或者在方法体内捕获。例如:IOException和ClassNotFoundException。

◆ 运行时异常(Unchecked Exception):这种异常不必在方法声明中指定,也不需要在方法体中捕获。例如:NumberFormatException。

因为run()方法不支持throws语句,所以当线程对象的run()方法抛出非运行异常时,我们必须捕获并且处理它们。当运行时异常从run()方法中抛出时,默认行为是在控制台输出堆栈记录并且退出程序。

好在,Java提供给我们一种在线程对象里捕获和处理运行时异常的一种机制。

在本节中,我们将通过范例学习这种机制。

准备工作
本节的范例是在Eclipse IDE里完成的。无论你使用Eclipse还是其他的IDE(比如NetBeans),都可以打开这个IDE并且创建一个新的Java工程。

范例实现
按照接下来的步骤实现本节的范例。

1.实现用来处理运行时异常的类。这个类实现UncaughtExceptionHandler接口并且实现这个接口的uncaughtException()方法。我们的范例将使用ExceptionHandler类的uncaughtException()方法打印出异常信息和抛出异常的线程代码。代码如下:

public class ExceptionHandler implements UncaughtExceptionHandler{
  public void uncaughtException(Thread t, Throwable e) {
    System.out.printf("An exception has been captured\n");
    System.out.printf("Thread: %s\n",t.getId());
    System.out.printf("Exception: %s: %s\n",e.getClass(). getName(),e.getMessage());
    System.out.printf("Stack Trace: \n");
    e.printStackTrace(System.out);
    System.out.printf("Thread status: %s\n",t.getState());
  }
}```
2.实现一个抛出运行时异常的线程类,命名为Task,它实现了Runnable接口,在实现run()方法时强制抛出运行时异常。例如,把一个String值转换成int值。

public class Task implements Runnable {
@Override
public void run() {
int numero=Integer.parseInt("TTT");
}
}```
3.实现范例的主程序。实现一个包含main()方法的Main类。

public class Main {
  public static void main(String[] args) {```
4.创建一个Task对象,并用它作为传入参数来创建一个Thread对象。接着调用setUncaughtExceptionHandler()方法设置线程的运行时异常处理器,然后启动这个线程。
Task task=new Task();
Thread thread=new Thread(task);
thread.setUncaughtExceptionHandler(new ExceptionHandler());
thread.start();

}
}```
5.运行范例并查看运行结果。

工作原理
下面的截屏记录了范例的运行结果。当异常抛出并被异常处理器捕获后,将在控制台打印出异常信息和抛出异常的线程代码。

当一个线程抛出了异常并且没有被捕获时(这种情况只可能是运行时异常),JVM检查这个线程是否被预置了未捕获异常处理器。如果找到,JVM将调用线程对象的这个方法,并将线程对象和异常作为传入参数。

如果线程没有被预置未捕获异常处理器,JVM将打印堆栈记录到控制台,并退出程序。

更多信息
Thread类还有另一个方法可以处理未捕获到的异常,即静态方法setDefaultUncaught ExceptionHandler()。这个方法在应用程序中为所有的线程对象创建了一个异常处理器。

当线程抛出一个未捕获到的异常时,JVM将为异常寻找以下三种可能的处理器。

首先,它查找线程对象的未捕获异常处理器。如果找不到,JVM继续查找线程对象所在的线程组(ThreadGroup)的未捕获异常处理器,这将在“线程组中不可控异常的处理”一节中讲解。如果还是找不到,如同本节所讲的,JVM将继续查找默认的未捕获异常处理器。

如果没有一个处理器存在,JVM则将堆栈异常记录打印到控制台,并退出程序。

时间: 2024-10-03 00:59:11

《Java程序员面试秘笈》—— 1.9 线程中不可控异常的处理的相关文章

《Java程序员面试秘笈》—— 面试题11 使用jar命令

面试题11 使用jar命令 Java程序员面试秘笈 请使用jar命令,将test文件夹压缩成.jar文件,并简述其压缩包的结构. 考点:对于Java程序员来说,更多情况下是使用的集成Java开发工具,例如JBuilder.Eclipse等,而对于最基本的Java编译和常见的命令行工具往往都不熟悉.这个面试题主要考察求职者对于Java命令行基本工具的使用,从而了解求职者对Java编程的熟悉程度. 出现频率: [面试题解析]熟练的Java开发者应该掌握常用的Java命令行工具.求职者应该熟练掌握ja

《Java程序员面试秘笈》—— 面试题12 如何执行mian()方法

面试题12 如何执行mian()方法 Java程序员面试秘笈 利用Java SDK中哪一条命令能够执行test的main()方法? (a)java test (b)javac test (c)java test.java (d)java test.class (e)java test.main 考点:考察求职者对java命令的熟悉程度. 出现频率: [面试题解析]求职者容易出现的错误是选择了(d).实际上,java命令后面只需要class文件的名称就可以,不用加入.class全名.如果使用jav

《Java程序员面试秘笈》—— 面试题10 类继承的建模表示方法

面试题10 类继承的建模表示方法 Java程序员面试秘笈根据图1.4的UML表示,选择一个正确的描述. (a)Box类是MyBox类的子类. (b)Box类是MyBox类的父类. (c)Box类和MyBox类是聚合关系. (d)Box类和MyBox类是一对多关系. 考点:该面试题貌似简单,在实际的面试中回答正确的却并不是很多,其实只是考察求职者对类的继承的建模表示方法的掌握程度. 出现频率: [面试题解析]Java中有两种机制来保证根据现有的类来构造新的类,那就是继承和聚合.例如,有一个盒子的类

《Java程序员面试秘笈》—— 导读

前言 Java 7并发编程实战手册 使用计算机时,可以同时做几件事情:可以一边听音乐,一边使用文字处理软件编辑文档,还可以阅读电子邮件.因为操作系统支持并发任务,从而使得这些工作得以同时进行.并发编程是一种平台和机制供多个任务或程序同时运行,并且互相通讯来交换数据(或者与其他任务进行同步等待). Java是一个并发平台,它提供了大量的类来执行Java程序中的并发任务.随着版本的不断更新发展,Java 不断地为程序员增加并发编程的开发功能.本书覆盖了Java 7并发API 中大部分重要而有用的机制

《Java程序员面试秘笈》—— 第1章 线程管理 1.1 简介

第1章 线程管理 Java 7并发编程实战手册 本章内容包括: ◆ 线程的创建和运行 ◆ 线程信息的获取和设置 ◆ 线程的中断 ◆ 线程中断的控制 ◆ 线程的休眠和恢复 ◆ 等待线程的终止 ◆ 守护线程的创建和运行 ◆ 线程中不可控异常的处理 ◆ 线程局部变量的使用 ◆ 线程的分组 ◆ 线程组中不可控异常的处理 ◆ 使用工厂类创建线程 1.1 简介 在计算机领域中,我们说的并发(Concurrency)是指一系列任务的同时运行.如果一台电脑有多个处理器或者有一个多核处理器,这个同时性(Simul

《Java程序员面试秘笈》—— 面试题6 命名Java变量

面试题6 命名Java变量 请命名以下变量. 考点:该面试题主要考察求职者的编程习惯,良好的编程习惯是一个优秀的Java开发者的必备素质.求职者应该掌握基本的Java命名规范,这样编写出来的代码才能做到够规范和易读. 出现频率: [面试题解析]在面向对象编程中,对于类.对象变量.方法等的命名是非常有技巧的,例如,大小写的区分,使用不同字母开头等.但究其本,追其源,在为一个资源命名时,应该本着描述性和唯一性两大特征,才能保证资源之间不冲突,并且便于记忆. 1.包的命名 Java包的名字都是由小写单

《Java程序员面试秘笈》—— 面试题1 简单描述Java开发包的种类

面试题1 简单描述Java开发包的种类 考点:考察求职者对于Java体系的认识,属于Java程序员的必备知识. 出现频率: [面试题解析]随着Java语言的成长和壮大,Java的开发包根据用途的不同已经分为Java EE.Java SE和Java ME 3个开发包,求职者需要列出名称,并具体描述每个开发包的用途. 参考答案: Java SDK的版本分类如下所述. Java ME:(Java Platform Micro Edition)一种以广泛的消费性产品为目的的高度优化的Java运行环境,包

《Java程序员面试秘笈》—— 1.2 线程的创建和运行

1.2 线程的创建和运行 在本章中,我们将学习如何在Java程序中创建和运行线程.在Java语言中,线程跟其他所有元素一样,都是对象(Object).Java提供了两种方式来创建线程: ◆ 继承Thread类,并且覆盖run()方法. ◆ 创建一个实现Runnable接口的类.使用带参数的Thread构造器来创建Thread对象.这个参数就是实现Runnable接口的类的一个对象. 在本章中,我们将使用第二种方法创建一个简单的程序,这个程序将创建并运行10个线程.每个线程用以计算和打印乘以1-1

《Java程序员面试秘笈》—— 1.12 线程组中不可控异常的处理

1.12 线程组中不可控异常的处理 提供应用程序中对错误情景的管理,是编程语言很重要的一面.和几乎所有的现代编程语言一样,Java语言也实现了通过异常管理机制来处理错误情景,它提供了很多类来表示不同的错误.当错误情景发生时,Java类将抛出这些异常.你可以使用这些异常,或者实现自己的异常,来管理类中的错误. Java也提供了捕获和处理这些异常的机制.有的异常必须被捕获,或者必须使用方法的throws声明再次抛出,这类异常叫做非运行时异常.还有一类异常叫做运行时异常,它们不需要被捕获或者声明抛出.