文档章节

线程中不可控异常的处理

柳哥
 柳哥
发布于 2015/04/26 12:20
字数 607
阅读 338
收藏 0

在Java中有两种异常。

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

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

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

好在,java提供给我们一种在线程对象里捕获和处理运行时异常的一种机制。实现用来处理运行时异常的类,这个类实现UncaughtExceptionHandler接口并且实现这个接口的uncaughtException()方法。示例:

package concurrency;

import java.lang.Thread.UncaughtExceptionHandler;

public class Main2 {
    public static void main(String[] args) {
        Task task = new Task();
        Thread thread = new Thread(task);
        thread.setUncaughtExceptionHandler(new ExceptionHandler());
        thread.start();
    }
}

class Task implements Runnable{
    @Override
    public void run() {
        int numero = Integer.parseInt("TTT");
    }
}

class ExceptionHandler implements UncaughtExceptionHandler{
    @Override
    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());
    }
}

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

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

当线程抛出一个未捕获到的异常时,JVM将为异常寻找以下三种可能的处理器。首先,它查找线程对象的未捕获异常处理器。如果找不到,JVM继续查找线程对象所在的线程组(ThreadGroup)的未捕获异常处理器(线程组后面blog在讲解)。如果还是找不到,如同本节所讲的,JVM将继续查找默认的未捕获异常处理器。如果没有一个处理器存在,JVM则将堆栈异常记录打印到控制台,并退出程序。


© 著作权归作者所有

共有 人打赏支持
柳哥
粉丝 203
博文 405
码字总数 347782
作品 0
杭州
技术主管
Java 并发编程(四) 线程池的创建与使用

一.前言 在项目中,避免不了要使用多线程,为了避免资源浪费和线程数的不可控而出现未知的问题,我们一般都会使用线程池; JDK中给我们提供了多种可以立即使用的创建线程池的方法,其都是基于Thr...

JackieRiver
09/13
0
0
华为手机或平板频繁出现的OOM异常

最近做平板应用,需要做一个循环扫描局域网IP端口的功能,实现原理是开一个线程池,然后将250个ping的线程加入其中开始运行,部分代码如下: 在其他机型上运行都无异常,华为设备上已有三例不...

Vonelone
03/17
0
0
线程组中不可控异常的处理

Java示例: package concurrency; import java.util.Random; public class Main6 { public static void main(String[] args) { MyThreadGroup threadGroup = new MyThreadGroup("MyThreadGro......

柳哥
2015/05/03
51
0
Java常用异常整理

填坑,整理下Java的常用异常。正确使用异常在实际编码中非常重要,但面试中的意义相对较小,因为对异常的理解和应用很难通过几句话或几行代码考查出来,不过我们至少应答出三点:异常类的继承...

monkeysayhi
2017/11/14
0
0
Golang处理大数据时使用高效的Pipeline(流水线)执行模型

Golang被证明非常适合并发编程,goroutine比异步编程更易读、优雅、高效。本文提出一个适合由Golang实现的Pipeline执行模型,适合批量处理大量数据(ETL)的情景。 想象这样的应用情景: (1...

火力全開
08/10
0
0

没有更多内容

加载失败,请刷新页面

加载更多

命令行新建Maven多项目

参考地址 # DgroupId 可以理解为包名# DartifactId 可以理解为项目名mvn archetype:generate -DgroupId=cn.modfun -DartifactId=scaffold -DarchetypeArtifactId=maven-archetype-quickst......

阿白
48分钟前
1
0
OSChina 周四乱弹 —— 上帝对我单身年限的惩罚越来越长了

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @达尔文:分享张卫健的单曲《身体健康》 《身体健康》- 张卫健 手机党少年们想听歌,请使劲儿戳(这里) 昨天是重阳节咯, 可惜小小编辑总是晚...

小小编辑
50分钟前
10
0
django rest framework 外键序列化方法与问题总结

django rest framework 外键序列化方法与问题总结 当借口中需要出现一对多关系的时候,我们可以用rest_framwork的序列化功能来处理,代码如下. # models.pyfrom django.db import modelscl...

_Change_
昨天
3
0
SingleNumber136 leetCode

Given a non-empty array of integers, every element appears twice except for one. Find that single one. Note: Your algorithm should have a linear runtime complexity. Could you im......

woshixin
昨天
3
0
String ,  StringBuffer ,  StringBuilder的区别

String , StringBuffer , StringBuilder的区别 String 首先,String 是用来表示一个字符串常量的,它是一个不可变对象,意味着,一旦我们创建了某个字符串之后,就不能再改变它的值了,我们可...

tsmyk0715
昨天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部