0018 Java多线程中UncheckedException异常处理UncaughtExceptionHandler【基础】

2 篇文章 0 订阅
1 篇文章 0 订阅

  提升工作效率利器:

‎Mac App Store 上的“Whale - 任务管理、时间、卡片、高效率”

Java编译器要求处理所有非运行时异常,否则程序不能编译通过。这类异常叫CheckedException

Java中还有一种异常叫做运行时异常,这种异常无需捕获,这类异常就叫做UncheckedException

多线程开发过程中,如果一个线程抛出了运行时异常因为无需捕获而未被处理,会导致线程终止。

下面一段话99%有误,需要查看JDK源码考证。

(正常情况下线程池中的线程执行完会挂起,放回线程池),这种不良影响在使用线程池时尤其明显,会直接导致线程池中的可用线程的数量因为异常挂起而减少,但是线程池中的poolsize数量却是不变,这样线程池丢失了一个线程,却没法创建新的线程,线程池中的总线程个数就永久的减少了一个。当线程池中的可用线程减少到0个时,再继续往该线程池里添加任务就会失败了。

注:针对上面的一段文字介绍,已经查看了JDK源码,如果线程池中线程挂死,线程池中的poolsize会减少,不会导致线程池中的可用线程永久减少一个。

下面转载一段写的比较好的,介绍如何处理运行时异常

Thread的run方法是不抛出任何检查型异常(checked exception)的(注意也不能抛,编译就不能通过),但是它自身却可能因为一个异常而被终止,导致这个线程的终结。最麻烦的是,在线程中抛出的异常即使在主线程中使用try...catch也无法截获,因此可能导致一些问题出现,比如异常的时候无法回收一些系统资源,或者没有关闭当前的连接等等。 

主线程之所以不处理子线程抛出的RuntimeException,是因为线程是异步的,子线程没结束,主线程可能已经结束了。 

UncaughtExceptionHandler名字意味着处理未捕获的异常。更明确的说,它处理未捕获的运行时异常。Java编译器要求处理所有非运行时异常,否则程序不能编译通过。这里“处理”的是方法里throws子句声明的异常或在try-catch块里的catch子句的异常。

[java]  view plain copy
  1. package demo;  
  2.   
  3. import java.lang.Thread.UncaughtExceptionHandler;  
  4.   
  5. public class ThreadTest  
  6. {  
  7.     public static void main(String[] args)  
  8.     {  
  9.         ThreadA a = null;  
  10.         try  
  11.         {  
  12.             ErrHandler handle = new ErrHandler();  
  13.             a = new ThreadA();  
  14.             a.setUncaughtExceptionHandler(handle);// 加入定义的ErrHandler  
  15.             a.start(); // 线程的run抛出的RuntimeException异常无法抓到
  16.             //(注:我自己试了一下,线程的run()方法不能throws Excetion)  
  17.             // a.run(); 普通方法抛出RuntimeException异常可以抓到  
  18.         }  
  19.         catch (Exception e)  
  20.         {  
  21.             System.out.println("catch RunTimeException a"); // 不起作用,但是Exception已经交给handle处理  
  22.         }  
  23.   
  24.         // 普通线程即使使用try...catch也无法捕获到抛出的异常  
  25.         try  
  26.         {  
  27.             ThreadB b = new ThreadB();  
  28.             b.start();  
  29.         }  
  30.         catch (Exception e)  
  31.         {  
  32.             System.out.println("catch RunTimeException b"); // 不起作用  
  33.         }  
  34.     }  
  35.   
  36. }  
  37.   
  38. /** 
  39.  * 自定义的一个UncaughtExceptionHandler 
  40.  */  
  41. class ErrHandler implements UncaughtExceptionHandler  
  42. {  
  43.     /** 
  44.      * 这里可以做任何针对异常的处理,比如记录日志等等 
  45.      */  
  46.     public void uncaughtException(Thread a, Throwable e)  
  47.     {  
  48.         System.out.println("This is:" + a.getName() + ",Message:" + e.getMessage());  
  49.         e.printStackTrace();  
  50.     }  
  51. }  
  52.   
  53. /** 
  54.  * 拥有UncaughtExceptionHandler的线程 
  55.  */  
  56. class ThreadA extends Thread  
  57. {  
  58.     public ThreadA()  
  59.     {  
  60.     }  
  61.   
  62.     public void run()  
  63.     {  
  64.         double i = 12 / 0;// 抛出ArithmeticException的RuntimeException型异常  
  65.     }  
  66. }  
  67.   
  68. /** 
  69.  * 普通线程 
  70.  */  
  71. class ThreadB extends Thread  
  72. {  
  73.     public ThreadB()  
  74.     {  
  75.     }  
  76.   
  77.     public void run()  
  78.     {  
  79.         try  
  80.         {  
  81.             double i = 12 / 0;// 抛出ArithmeticException的RuntimeException型异常  
  82.         }  
  83.         catch (RuntimeException e)  
  84.         {  
  85.             throw e;  
  86.         }  
  87.     }  
  88. }  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值