欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

博弈Java讲义 - Java线程之uncontrolled exceptions

程序员文章站 2022-07-12 20:15:16
...

前两天翻阅《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都没有找到,这默认打出错误栈并推出程序。 
  让们看一个具体的例子: 
  

Java代码 
  1.   import java.lang.Thread.UncaughtExceptionHandler;  
  2.   
  3. public class MyUncaughtExceptionHandler implements UncaughtExceptionHandler {  
  4.   
  5.     @Override  
  6.     public void uncaughtException(Thread t, Throwable e) {  
  7.         System.out.printf("Uncaught exception raised and captured in thread  %s : \n", t.getName());  
  8.     }  
  9.   
  10. }  
  11.   
  12. import java.lang.Thread.UncaughtExceptionHandler;  
  13.   
  14. public class MyUncaughtExceptionHandler implements UncaughtExceptionHandler {  
  15.   
  16.     @Override  
  17.     public void uncaughtException(Thread t, Throwable e) {  
  18.         System.out.printf("Uncaught exception raised and captured in thread  %s : \n", t.getName());  
  19.     }  
  20.   
  21. }  
  22.   
  23. public class MyThreadGroupWithExceptionHandler extends ThreadGroup {  
  24.   
  25.     public MyThreadGroupWithExceptionHandler(String name) {  
  26.         super(name);  
  27.     }  
  28.   
  29.     @Override  
  30.     public void uncaughtException(Thread t, Throwable e) {  
  31.         System.out.printf("Uncaught exception caught in thread group's uncaughtException %s.\n",this.getName());  
  32.         interrupt();  
  33.     }  
  34.       
  35. }  
  36. public class TestUncaughtException {  
  37.   
  38.     public static void main(String[] args){  
  39.         MyTask task1 = new MyTask();  
  40.         Thread t1 = new Thread(task1,"UncaughtException Task");  
  41.         t1.setUncaughtExceptionHandler(new MyUncaughtExceptionHandler());  
  42.         t1.start();  
  43.       
  44.           
  45.         MyThreadGroupWithExceptionHandler group1 = new MyThreadGroupWithExceptionHandler("mythread");  
  46.         MyTask task2 = new MyTask();  
  47.         Thread t2 = new Thread(group1, task2,"Task with group exception handler");  
  48.         t2.start();  
  49.           
  50.         ThreadGroup group2 = new ThreadGroup("mythread");  
  51.         MyTask task3 = new MyTask();  
  52.         Thread.setDefaultUncaughtExceptionHandler(new MyDefaultExceptionHandler());  
  53.         Thread t3 = new Thread(group2, task3, "Task with exception caught by Thread.default");  
  54.         t3.start();  
  55.           
  56.     }  
  57.       
  58. }  


  输出可见异常分别在Thread实例,ThreadGroup,Thread级别被捕获。