前两天翻阅《Effective Java》发现一条提示慎用线程组。ThreadGroup提供的很多功能的实现是有瑕疵的。例如,我们可以调用activeCount获得该组中活动线程的数量,一旦这个数组进行了分配,并用enumerate方法遍历,如果线程数增加了,就有可能忽略掉调用activeCount后新增的线程。关于处理线程组逻辑,可以用线程池的executor代替。class="Apple-converted-space">?
? 也许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都没有找到,这默认打出错误栈并推出程序。?
? 让们看一个具体的例子:?
??
Java代码
?
- ??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级别被捕获。?