Java并发编程示例(八):处理线程的非受检异常
Java语言中,把异常分为两类:
受检异常:这类异常必须在throws子句中被显式抛出或者在方法内被捕获。例如,IOException异常或ClassNotFoundException异常。
非受检异常:这类异常不需要显式抛出或捕获。例如,NumberFormatException异常。
当一个受检异常在Thread对象的run()方法中被抛出时,我们必须捕获并处理它,因为run()方法不能抛出异常。而一个非受检异常在Thread对象的run()方法中被抛出时,默认的行为是在控制台打印出堆栈跟踪信息然后退出程序。
幸运的是,Java为我们提供了一种机制,专门用于处理由Thread对象抛出的非受检异常,以避免程序的退出。
在本节,我们用示例来演示这种机制。
知其然
按照下面所示步骤来实现我们的示例。
1.首先,我们需要实现一个用于处理非受检异常的类。这个类必须实现UncaughtExceptionHandler类,实现在该接口中声明的uncaughtException()方法。在本例中,该类名为ExceptionHandler,uncaughtException()方法将异常以及抛出异常的线程信息打印出来。代码如下:
publicclassExceptionHandlerimplementsThread.UncaughtExceptionHandler{ @Override publicvoiduncaughtException(Threadt,Throwablee){ System.out.printf("Anexceptionhasbeencaptured\\n"); System.out.printf("Thread:%s\n",t.getId()); System.out.printf("Exception:%s:%s\n",e.getClass().getName(), e.getMessage()); System.out.printf("StackTrace:\n"); e.printStackTrace(System.out); System.out.printf("Threadstatus:%s\n",t.getState()); } }
2.实现一个可以抛出非受检异常的类,称为Task,实现Runnable接口,实现run()方法,特意编码一段可以产生非受检异常的代码,例如,将字符串转换成数字。代码如下:
publicclassTaskimplementsRunnable{ @Override publicvoidrun(){ intnumero=Integer.parseInt("diguage.com"); } }
3.创建程序的主类,Main类,然后实现main()方法。代码如下:
publicclassMain{ publicstaticvoidmain(String[]args){
4.创建Task对象,并且创建一个Thread对象来执行之。使用setUncaughtExceptionHandler()方法设置非受检异常的处理类。然后,启动线程。代码如下:
Tasktask=newTask(); Threadthread=newThread(task); thread.setUncaughtExceptionHandler(newExceptionHandler()); thread.start();
5.运行示例,查看结果。
知其所以然
从下面的输出片段可以看出异常执行的结果。异常被抛出,然后被处理类捕获并将异常信息打印到了控制台。
Anexceptionhasbeencaptured Thread:9 Exception:java.lang.NumberFormatException:Forinputstring:"diguage.com" StackTrace: java.lang.NumberFormatException:Forinputstring:"diguage.com" atjava.lang.NumberFormatException.forInputString(NumberFormatException.java:65) atjava.lang.Integer.parseInt(Integer.java:492) atjava.lang.Integer.parseInt(Integer.java:527) atcom.diguage.books.concurrencycookbook.chapter1.recipe8.Task.run(Task.java:13) atjava.lang.Thread.run(Thread.java:722) Threadstatus:RUNNABLE
Processfinishedwithexitcode0