1. 程式人生 > >執行緒中不可控制異常的處理

執行緒中不可控制異常的處理

1、異常

Exception:它指出了合理的應用程式想要捕獲的條件。

Exception又分為兩類:一種是CheckedException(非執行時異常),一種是UncheckedException(執行時異常)。這兩種Exception的區別主要是CheckedException需要用try...catch...顯示的捕獲,而UncheckedException不需要捕獲。通常UncheckedException又叫做RuntimeException。《effective java》指出:對於可恢復的條件使用被檢查的異常(CheckedException),對於程式錯誤(言外之意不可恢復,大錯已經釀成)使用執行時異常(RuntimeException)。

常見的RuntimeExcepiton有IllegalArgumentException、IllegalStateException、NullPointerException、NumberFormatException、IndexOutOfBoundsException等等。對於那些CheckedException就不勝列舉了,在編寫程式過程中try...catch...捕捉的異常都是CheckedException。io包中的IOException及其子類,ClassNotFoundException,這些都是CheckedException。

run方法不支援throws語句,所以當執行緒物件的run()方法丟擲非執行異常時,必須捕獲並且處理它們。當執行時異常從run()方法中丟擲時,預設行為是在控制檯輸出堆疊記錄並且退出程式。

2、程式碼事例

package com.xxx.util;

/**
 * Created with IntelliJ IDEA.
 * Date: 15-3-31
 * Time: 上午10:26
 * To change this template use File | Settings | File Templates.
 */
public class ThreadException implements Thread.UncaughtExceptionHandler {

    @Override
    public void uncaughtException(Thread t, Throwable e) {
        System.out.printf("An exception has been captured\n");
        System.out.printf("Thread:%s\n",t.getId());
        System.out.printf("Exception:%s:%s\n",e.getClass().getName(),e.getMessage());
        System.out.println("Stack Trace:");
        e.printStackTrace(System.out);
        System.out.printf("Thread status:%s\n",t.getState());
    }
}
package com.xxx.util;

/**
 * Created with IntelliJ IDEA.
 * Date: 15-3-31
 * Time: 上午10:39
 * To change this template use File | Settings | File Templates.
 */
public class ThreadExceptionRun implements Runnable {
    @Override
    public void run() {
        int i = Integer.parseInt("sss");
        System.out.println(i);
    }
}
package com.xxx.util;

/**
 * Created with IntelliJ IDEA.
 * Date: 15-3-31
 * Time: 上午10:33
 * To change this template use File | Settings | File Templates.
 */
public class ThreadExceptionMain {

    public static void main(String[] args){
        Thread thread = new Thread(new ThreadExceptionRun());
        thread.setUncaughtExceptionHandler(new ThreadException());
        thread.start();
    }

}
3、執行結果




4、結論

java為我們提供了一種執行緒內發生異常時能夠線上程程式碼邊界之外處理異常的回撥機制,即Thread物件提供的setUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh)方法。通過該方法給某個thread設定一個UncaughtExceptionHandler,可以確保在該執行緒出現異常時能通過回撥UncaughtExceptionHandler介面的public void uncaughtException(Thread t, Throwable e) 方法來處理異常,這樣的好處或者說目的是可以線上程程式碼邊界之外(Thread的run()方法之外),有一個地方能處理未捕獲異常。但是要特別明確的是:雖然是在回撥方法中處理異常,但這個回撥方法在執行時依然還在丟擲異常的這個執行緒中!另外還要特別說明一點:如果執行緒是通過執行緒池建立,執行緒異常發生時UncaughtExceptionHandler介面不一定會立即回撥。