免费A级毛片无码专区网站-成人国产精品视频一区二区-啊 日出水了 用力乖乖在线-国产黑色丝袜在线观看下-天天操美女夜夜操美女-日韩网站在线观看中文字幕-AV高清hd片XXX国产-亚洲av中文字字幕乱码综合-搬开女人下面使劲插视频

Java線程未捕獲異常處理 UncaughtExceptionHandler

當一個線程在執(zhí)行過程中拋出了異常,并且沒有進行try..catch,那么這個線程就會終止運行 。在Thread類中,提供了兩個可以設(shè)置線程未捕獲異常的全局處理器,我們可以在處理器里做一些工作,例如將異常信息發(fā)送到遠程服務(wù)器 。雖然這可以捕獲到線程中的異常,但是并不能阻止線程停止運行 。因此該在線程run方法里try..catch的,還是要好好的進行try..catch 。
從Thread類源代碼中可以看到這2個變量:
private volatile UncaughtExceptionHandler uncaughtExceptionHandler;private static volatile UncaughtExceptionHandler defaultUncaughtExceptionHandler;需要注意到區(qū)別,defaultUncaughtExceptionHandler是靜態(tài)的,我們可以調(diào)用此方法設(shè)置所有線程對象的異常處理器,而uncaughtExceptionHandler則是針對單個線程對象的異常處理器 。
uncaughtExceptionHandler優(yōu)先級高于defaultUncaughtExceptionHandler 。
Thread類提供了這2個變量的setter/getter:
public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) {    SecurityManager sm = System.getSecurityManager();    if (sm != null) {        sm.checkPermission(            new RuntimePermission("setDefaultUncaughtExceptionHandler")          );    }     defaultUncaughtExceptionHandler = eh; }    public static UncaughtExceptionHandler getDefaultUncaughtExceptionHandler(){    return defaultUncaughtExceptionHandler;}public UncaughtExceptionHandler getUncaughtExceptionHandler() {    return uncaughtExceptionHandler != null ?        uncaughtExceptionHandler : group;}public void setUncaughtExceptionHandler(UncaughtExceptionHandler eh) {    checkAccess();    uncaughtExceptionHandler = eh;}可以看到,getUncaughtExceptionHandler()中進行了判斷,當uncaughtExceptionHandler為null時返回group 。
我們來看下UncaughtExceptionHandler接口是怎么聲明的:
@FunctionalInterfacepublic interface UncaughtExceptionHandler {    void uncaughtException(Thread t, Throwable e);}我們只需要實現(xiàn)UncaughtExceptionHandler接口,重寫uncaughtException方法即可進行異常處理 。
那么JVM是怎么檢測到線程發(fā)生異常,并將異常分發(fā)到處理器的呢?對于這塊代碼,JDK源碼中看不到是如何處理的,可能需要翻閱hotspot源碼,不過Thread類中提供了一個dispatchUncaughtException方法,將異?;卣{(diào)到了uncaughtExceptionHandler中去處理 。
private void dispatchUncaughtException(Throwable e) {    getUncaughtExceptionHandler().uncaughtException(this, e);}很明顯,dispatchUncaughtException應(yīng)該就是提供給hotspot進行JNI回調(diào)的 。而對于defaultUncaughtExceptionHandler的調(diào)用,猜測應(yīng)該是在hotspot中直接完成了 。
接下來我們用示例來演示一下異常處理器的效果 。
示例:
Thread thread = new Thread(() -> {    System.out.println("run before");    System.out.println("runing");    if(1 == 1) {        throw new IllegalStateException("exception");    }    System.out.println("run after");});thread.setUncaughtExceptionHandler((t, e) -> System.out.println("捕獲異常," + t.getName() + "," + e.getMessage()));Thread.setDefaultUncaughtExceptionHandler((t, e) -> System.out.println("Default捕獲異常," + t.getName() + "," + e.getMessage()));thread.start();輸出:
run beforeruning捕獲異常,Thread-0,exception可以看出,雖然兩個異常處理器都有設(shè)置,并且defaultUncaughtExceptionHandler是最后設(shè)置的,不過起效的是uncaughtExceptionHandler 。
可以將thread.setUncaughtExceptionHandler(...);注釋掉:輸出:

經(jīng)驗總結(jié)擴展閱讀