這篇文章主要介紹了JAVA如何處理未捕獲異常,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
JVM為我們提供了線程的未捕獲異常處理機制,通過Thread的setUncaughtExceptionHandler方法:
public void setUncaughtExceptionHandler(UncaughtExceptionHandler eh)
可以設置當前線程的未捕獲異常處理器。如下面的例子就通過設置uncaughtExceptionHandler成功捕獲到了除0異常:
public static void main(String[] args) throws InterruptedException { Thread t = new Thread(new UncaughtException.Run());
t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {@Override
br/>@Override<br/public void run() {
System.out.println("runnable run---------------");
int i = 1/0;
}
}
結果:
runnable run---------------
uncaughtExceptionHandler catch a Exception---------
/ by zero
線程出現未捕獲異常后,JVM將調用Thread中的dispatchUncaughtException方法把異常傳遞給線程的未捕獲異常處理器。
/**
Dispatch an uncaught exception to the handler. This method is
intended to be called only by the JVM.
*/
private void dispatchUncaughtException(Throwable e) {
getUncaughtExceptionHandler().uncaughtException(this, e);
}
方法的描述已經清楚地說明了這個方法只是提供給JVM調用的,getUncaughtExceptionHandler方法并沒有簡單返回設置好的uncaughtExceptionHandler:
public UncaughtExceptionHandler getUncaughtExceptionHandler() {
return uncaughtExceptionHandler != null ?
uncaughtExceptionHandler : group;
}
可見,如果沒有設置uncaughtExceptionHandler,將使用線程所在的線程組來處理這個未捕獲異常。線程組ThreadGroup實現了UncaughtExceptionHandler,所以可以用來處理未捕獲異常。ThreadGroup類定義:
class ThreadGroup implements Thread.UncaughtExceptionHandler
ThreadGroup實現的uncaughtException如下:
public void uncaughtException(Thread t, Throwable e) {
if (parent != null) {
parent.uncaughtException(t, e);
} else {
Thread.UncaughtExceptionHandler ueh =
Thread.getDefaultUncaughtExceptionHandler();
if (ueh != null) {
ueh.uncaughtException(t, e);
} else if (!(e instanceof ThreadDeath)) {
System.err.print("Exception in thread \""
t.getName() + "\" ");
e.printStackTrace(System.err);
}
}
}
默認情況下,線程組處理未捕獲異常的邏輯是,首先將異常消息通知給父線程組,然后嘗試利用一個默認的defaultUncaughtExceptionHandler來處理異常,如果沒有默認的異常處理器則將錯誤信息輸出到System.err。也就是JVM提供給我們亨達返傭www.fx61.com/brokerlist/HantecGlobal.html設置每個線程的具體的未捕獲異常處理器,也提供了設置默認異常處理器的方法。
設置了默認的異常處理器后,系統中所有未直接設置異常處理器的線程將使用這個默認的異常處理器。
public void defaultWay(){
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {@Override
br/>@Override<br/public void run() {
int i = 1/0;
}
}, "thread1").start();
new Thread(myGroup, new Runnable() {@Override
br/>super(name);
}
@Override<br/public void uncaughtException(Thread t, Throwable e) {
System.out.println("I am a bad group and do nothing");
}
}
如果使用了BadGroup得出結果將是打印兩條I am a bad group and do nothing。
上面的例子中,不論是ThreadGroup或者BadGroup都主動的給線程設置了線程組,那么如果不給線程設置線程組會怎么樣呢?還會正常的使用默認異常處理器嗎?這些跟線程組的來源相關,先看一個例子:
public void mainGroup() throws InterruptedException {
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {@Override
br/>@Override<br/public void run() {
System.out.println(Thread.currentThread().getName() + " said my thread group is " + Thread.currentThread().getThreadGroup().getName());
new Thread(new Runnable() {@Override
br/>@Override<br/public void uncaughtException(Thread t, Throwable e) {
System.out.println("捕獲異常處理方法:" + e);
}
}
我們有三種方式使用該線程異常捕獲器:
1、在創建線程的時候進行設置
Thread t = new Thread(new ExceptionThread());
t.setUncaughtExceptionHandler(new MyUnchecckedExceptionhandler());
t.start();
2、使用Executors創建線程時,還可以在TreadFactory中設置
ExecutorService exec = Executors.newCachedThreadPool(new ThreadFactory(){@Override<br/" rel="nofollow">br/>@Override<br/ public Thread newThread(Runnable r) {
Thread thread = newThread(r);
thread.setUncaughtExceptionHandler(new MyUnchecckedExceptionhandler());
return thread;
}
});
exec.execute(new ExceptionThread());
3、如果我們只需要一個線程異常處理器處理線程的異常,那么我們可以設置一個默認的線程異常捕獲器,當線程出現異常時,
如果我們沒有指定線程的異常捕獲器,而且線程組也沒有設置(線程組不用考慮,因為這是一個不成功的嘗試),那么就會使用
默認的線程異常捕獲器。
// 設置默認的線程異常捕獲處理器
Thread.setDefaultUncaughtExceptionHandler(new MyUnchecckedExceptionhandler());
通過以上方法就可以捕獲并處理線程的異常了。
感謝你能夠認真閱讀完這篇文章,希望小編分享的“JAVA如何處理未捕獲異?!边@篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。