在線程的run方法中,如果有受檢異常必須進行捕獲處理,如果想要獲得run()方法中出現(xiàn)的運行時異常信息,可以通過回調(diào)UncaughtExceptionHandler接口獲得哪個線程出現(xiàn)了運行時異常,在Thread類中有關處理運行異常的方法有:
getDefaultUncaughtExceptionHandler() 獲得全局的(默認的)UncaughtExceptionHandler。
getUncaughtExceptionHandler() 獲得當前線程的UncaughtExceptionHandler。
setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh) 設置全局的UncaughtExceptionHandler。
setUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh) 設置當前線程的UncaughtExceptionHandler。
當線程運行過程中出現(xiàn)異常,JVM會調(diào)用Thread類的dispatchUncaughtException(Throwable e)方法, 該方法會調(diào)用getUncaughtExceptionHandler().uncaughtException(this, e); 如果想要獲得線程中出現(xiàn)異常的信息,就需要設置線程的UncaughtExceptionHandler。
package com.wkcto.threadexception;
import java.io.FileInputStream;
/**
* 演示設置線程的UnCaughtExceptionHandler回調(diào)接口
*/
public class Test01 {
public static void main(String[] args) {
//1)設置線程全局的回調(diào)接口
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
//t參數(shù)接收發(fā)生異常的線程, e就是該線程中的異常
System.out.println(t.getName() + "線程產(chǎn)生了異常: " + e.getMessage());
}
});
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "開始運行");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
//線程中的受檢異常必須捕獲處理
e.printStackTrace();
}
System.out.println(12 / 0 ); //會產(chǎn)生算術異常
}
});
t1.start();
new Thread(new Runnable() {
@Override
public void run() {
String txt = null;
System.out.println( txt.length()); //會產(chǎn)生空指針異常
}
}).start();
/*
在實際開發(fā)中,這種設計異常處理的方式還是比較常用的,尤其是異常執(zhí)行的方法
如果線程產(chǎn)生了異常, JVM會調(diào)用dispatchUncaughtException()方法,在該方法中調(diào)用了getUncaughtExceptionHandler().uncaughtException(this, e); 如果當前線程設置了UncaughtExceptionHandler回調(diào)接口就直接調(diào)用它自己的uncaughtException方法, 如果沒有設置則調(diào)用當前線程所在線程組UncaughtExceptionHandler回調(diào)接口的uncaughtException方法,如果線程組也沒有設置回調(diào)接口,則直接把異常的棧信息定向到System.err中
*/
}
}