Listing4-1 从方法run()方法中抛出异常。
package com.owen.thread.chapter4; public class ExceptionThread { public static void main(String[] args) { Runnable r = new Runnable() { @Override public void run() { int x = 1 / 0; // Line 10 } }; Thread thd = new Thread(r); thd.start(); } } 在默认主线程创建一个runnable,我们故意让整数除以0然后抛出一个ArithmeticException对象。 执行这段代码,你将会看到如下的异常: Exception in thread "Thread-0" java.lang.ArithmeticException: / by zero at com.owen.thread.chapter4.ExceptionThread$1.run(ExceptionThread.java:13) at java.lang.Thread.run(Thread.java:745) 当一个异常从run()方法抛出时,这个线程将会结束,并且下面的活动将会取代它: (1)Java虚拟机(JVM)寻找一个实例的Thread。通过Thread的void setUncaughtException(Thread.UncaughtException eh)方法实例一个Thread.UncaughtExceptionHandler。当这个实例被找到之后,它将会通过执行实例的void uncaughtException(Thread t, Throwable e)方法,去抛出异常或错误——可能是一个java.lang.outOfMemoryError对象抛出;方法中的t明确Thread对象,和e明确抛出异常或错误。如果uncaughtException()抛出一个异常或错误,这个异常或错误将会被java虚拟机忽略。 (2)假设setUncaughtExceptionHandler()不会被请求给任命的操控,那么Java虚拟机(JVM)通过控制着连接ThreadGroup对象uncaughtExeption(Thread t, Throwable r)方法。假设ThreadGroup不被扩展和它的uncaughtException()方法不能继承和uncaughtException()方法不能重载去操作异常;当父级的ThreadGroup存在时。uncaughtException通过控制父级的ThreadGroup对象的uncaughtException()方法。否则,线程将会去检查是否有其它的默认不能捕抓异常出现(通过Thread的static void setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler handler)方法)。如果默认不能捕抓的异常存在,它的uncaughtException()方法将被两个相同的参数请求。否则,uncaughtException()检查它的Throwable参数去确定是否它的一个java.lang.ThreadDeath存在。如果存在,不会做什么特殊事。另外,如Listing4-1期待的信息展示,一个信息包含一个线程的名称,和一个栈的撤消,运用Throwable参数的printStackTrace()方法,它将会打印出标准的错误流。 Listing4-2证明Thread的setUncaughtExceptionHandler()和setDefaultUncaughtExceptionHandler()方法。 Listing4-2证明不能捕抓异常操作。 package com.owen.thread.chapter4; public class ExceptionThread4_2 { public static void main(String[] args) { Runnable r = new Runnable() { @Override public void run() { int x = 1 / 0; } }; Thread thd = new Thread(r); Thread.UncaughtExceptionHandler uceh; uceh = new Thread.UncaughtExceptionHandler() { @Override public void uncaughtException(Thread t, Throwable e) { System.out.println("Caught throwable " + e + " for thread " + t); } }; thd.setUncaughtExceptionHandler(uceh); uceh = new Thread.UncaughtExceptionHandler() { @Override public void uncaughtException(Thread t, Throwable e) { System.out.println("Default uncaught exception handler"); System.out.println("Caught throwable " + e + " for thread " + t); } }; thd.setDefaultUncaughtExceptionHandler(uceh); thd.start(); } } 执行这个代码,你将得到如下的异常: Caught throwable java.lang.ArithmeticException: / by zero for thread Thread[Thread-0,5,main] 你不能看到默认非捕抓异常操作输出信息,因为默认操作不会被请求。为了看到默认异常输出,你必须注释掉thd.setUncaughtExceptionHandler(uche);.如果你也注释掉了thd.setDefaultUncaughtExceptionHandler(uceh);,那么你将会看Listing4-1的输出信息。源码下载:git@github.com:owenwilliam/Thread.git