您好,登錄后才能下訂單哦!
這篇文章主要介紹了JAVA如何處理未捕獲異常,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
JVM為我們提供了線程的未捕獲異常處理機(jī)制,通過Thread的setUncaughtExceptionHandler方法:
public void setUncaughtExceptionHandler(UncaughtExceptionHandler eh)
可以設(shè)置當(dāng)前線程的未捕獲異常處理器。如下面的例子就通過設(shè)置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;
}
}
結(jié)果:
runnable run---------------
uncaughtExceptionHandler catch a Exception---------
/ by zero
線程出現(xiàn)未捕獲異常后,JVM將調(diào)用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);
}
方法的描述已經(jīng)清楚地說明了這個(gè)方法只是提供給JVM調(diào)用的,getUncaughtExceptionHandler方法并沒有簡(jiǎn)單返回設(shè)置好的uncaughtExceptionHandler:
public UncaughtExceptionHandler getUncaughtExceptionHandler() {
return uncaughtExceptionHandler != null ?
uncaughtExceptionHandler : group;
}
可見,如果沒有設(shè)置uncaughtExceptionHandler,將使用線程所在的線程組來處理這個(gè)未捕獲異常。線程組ThreadGroup實(shí)現(xiàn)了UncaughtExceptionHandler,所以可以用來處理未捕獲異常。ThreadGroup類定義:
class ThreadGroup implements Thread.UncaughtExceptionHandler
ThreadGroup實(shí)現(xiàn)的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);
}
}
}
默認(rèn)情況下,線程組處理未捕獲異常的邏輯是,首先將異常消息通知給父線程組,然后嘗試?yán)靡粋€(gè)默認(rèn)的defaultUncaughtExceptionHandler來處理異常,如果沒有默認(rèn)的異常處理器則將錯(cuò)誤信息輸出到System.err。也就是JVM提供給我們亨達(dá)返傭www.fx61.com/brokerlist/HantecGlobal.html設(shè)置每個(gè)線程的具體的未捕獲異常處理器,也提供了設(shè)置默認(rèn)異常處理器的方法。
設(shè)置了默認(rèn)的異常處理器后,系統(tǒng)中所有未直接設(shè)置異常處理器的線程將使用這個(gè)默認(rèn)的異常處理器。
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得出結(jié)果將是打印兩條I am a bad group and do nothing。
上面的例子中,不論是ThreadGroup或者BadGroup都主動(dòng)的給線程設(shè)置了線程組,那么如果不給線程設(shè)置線程組會(huì)怎么樣呢?還會(huì)正常的使用默認(rèn)異常處理器嗎?這些跟線程組的來源相關(guān),先看一個(gè)例子:
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、在創(chuàng)建線程的時(shí)候進(jìn)行設(shè)置
Thread t = new Thread(new ExceptionThread());
t.setUncaughtExceptionHandler(new MyUnchecckedExceptionhandler());
t.start();
2、使用Executors創(chuàng)建線程時(shí),還可以在TreadFactory中設(shè)置
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、如果我們只需要一個(gè)線程異常處理器處理線程的異常,那么我們可以設(shè)置一個(gè)默認(rèn)的線程異常捕獲器,當(dāng)線程出現(xiàn)異常時(shí),
如果我們沒有指定線程的異常捕獲器,而且線程組也沒有設(shè)置(線程組不用考慮,因?yàn)檫@是一個(gè)不成功的嘗試),那么就會(huì)使用
默認(rèn)的線程異常捕獲器。
// 設(shè)置默認(rèn)的線程異常捕獲處理器
Thread.setDefaultUncaughtExceptionHandler(new MyUnchecckedExceptionhandler());
通過以上方法就可以捕獲并處理線程的異常了。
感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“JAVA如何處理未捕獲異?!边@篇文章對(duì)大家有幫助,同時(shí)也希望大家多多支持億速云,關(guān)注億速云行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。