由浅入深Java线程之uncontrolled exceptions

前两天翻阅《Effective Java》发现一条提示慎用线程组。ThreadGroup提供的很多功能的实现是有瑕疵的。例如,我们可以调用activeCount获得该组中活动线程的数量,一旦这个数组进行了分配,并用enumerate方法遍历,如果线程数增加了,就有可能忽略掉调用activeCount后新增的线程。关于处理线程组逻辑,可以用线程池的executor代替。
也许ThreadGroup提供的有用的功能之一就是uncaughtException方法了。Java提供了强大的异常处理机制,有些异常可以通过try/catch捕获或者re-throw,这些都是checked exception,比如IOException和ClassNotFoundException,还有一些是不必要捕获处理的,如NumberFormatException.
在Java多线程中提供了一个层次化的机制帮助我们有效的处理uncaught exception. 当一个线程抛出异常时,JVM首先会调用thread里面指定的uncaught exception handler处理异常,如果在thread级没有设置handler,JVM会到当前线程所在的组的exception handler处理异常,如果线程组没有定义uncaughtException方法,JVM会继续寻找上一级的exception handler处理。如果一个handler都没有找到,这默认打出错误栈并推出程序。
让们看一个具体的例子:

  import java.lang.Thread.UncaughtExceptionHandler;

public class MyUncaughtExceptionHandler implements UncaughtExceptionHandler {

@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.printf("Uncaught exception raised and captured in thread %s : \n", t.getName());
}

}

import java.lang.Thread.UncaughtExceptionHandler;

public class MyUncaughtExceptionHandler implements UncaughtExceptionHandler {

@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.printf("Uncaught exception raised and captured in thread %s : \n", t.getName());
}

}

public class MyThreadGroupWithExceptionHandler extends ThreadGroup {

public MyThreadGroupWithExceptionHandler(String name) {
super(name);
}

@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.printf("Uncaught exception caught in thread group's uncaughtException %s.\n",this.getName());
interrupt();
}

}
public class TestUncaughtException {

public static void main(String[] args){
MyTask task1 = new MyTask();
Thread t1 = new Thread(task1,"UncaughtException Task");
t1.setUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
t1.start();


MyThreadGroupWithExceptionHandler group1 = new MyThreadGroupWithExceptionHandler("mythread");
MyTask task2 = new MyTask();
Thread t2 = new Thread(group1, task2,"Task with group exception handler");
t2.start();

ThreadGroup group2 = new ThreadGroup("mythread");
MyTask task3 = new MyTask();
Thread.setDefaultUncaughtExceptionHandler(new MyDefaultExceptionHandler());
Thread t3 = new Thread(group2, task3, "Task with exception caught by Thread.default");
t3.start();

}

}

输出可见异常分别在Thread实例,ThreadGroup,Thread级别被捕获。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值