Java並發編程示例(八):處置線程的非受檢異常。本站提示廣大學習愛好者:(Java並發編程示例(八):處置線程的非受檢異常)文章只能為提供參考,不一定能成為您想要的結果。以下是Java並發編程示例(八):處置線程的非受檢異常正文
Java說話中,把異常分為兩類:
受檢異常: 這類異常必需在throws子句中被顯式拋出或許在辦法內被捕捉。例如,IOException異常或ClassNotFoundException異常。
非受檢異常: 這類異常不須要顯式拋出或捕捉。例如,NumberFormatException異常。
當一個受檢異常在Thread對象的run()辦法中被拋出時,我們必需捕捉並處置它,由於run()辦法不克不及拋出異常。而一個非受檢異常在Thread對象的run()辦法中被拋出時,默許的行動是在掌握台打印出客棧跟蹤信息然撤退退卻出法式。
榮幸的是,Java為我們供給了一種機制,專門用於處置由Thread對象拋出的非受檢異常,以免法式的加入。
在本節,我們用示例來演示這類機制。
知其然
依照上面所示步調來完成我們的示例。
1.起首,我們須要完成一個用於處置非受檢異常的類。這個類必需完成UncaughtExceptionHandler類,完成在該接口中聲明的uncaughtException()辦法。在本例中,該類名為ExceptionHandler,uncaughtException()辦法將異常和拋出異常的線程信息打印出來。代碼以下:
public class ExceptionHandler 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.printf("Stack Trace: \n");
e.printStackTrace(System.out);
System.out.printf("Thread status: %s\n", t.getState());
}
}
2.完成一個可以拋出非受檢異常的類,稱為Task,完成Runnable接口,完成run()辦法,特地編碼一段可以發生非受檢異常的代碼,例如,將字符串轉換成數字。代碼以下:
public class Task implements Runnable {
@Override
public void run() {
int numero = Integer.parseInt("diguage.com");
}
}
3.創立法式的主類,Main類,然後完成main()辦法。代碼以下:
public class Main {
public static void main(String[] args) {
4.創立Task對象,而且創立一個Thread對象來履行之。應用setUncaughtExceptionHandler() 辦法設置非受檢異常的處置類。然後,啟動線程。代碼以下:
Task task = new Task();
Thread thread = new Thread(task);
thread.setUncaughtExceptionHandler(new ExceptionHandler());
thread.start();
5.運轉示例,檢查成果。
知其所以然
從上面的輸入片斷可以看出異常履行的成果。異常被拋出,然後被處置類捕捉並將異常信息打印到了掌握台。
An exception has been captured
Thread: 9
Exception: java.lang.NumberFormatException: For input string: "diguage.com"
Stack Trace:
java.lang.NumberFormatException: For input string: "diguage.com"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:492)
at java.lang.Integer.parseInt(Integer.java:527)
at com.diguage.books.concurrencycookbook.chapter1.recipe8.Task.run(Task.java:13)
at java.lang.Thread.run(Thread.java:722)
Thread status: RUNNABLE
Process finished with exit code 0
當一個線程拋出一個異常,而且該異常(這裡特指非受檢異常)沒有捕捉時,Java虛擬機遇檢討能否經由過程響應辦法設置非受檢異常處置類,假如以曾經設置過,則挪用uncaughtException()辦法,並將線程和異常作為參數傳遞給辦法。
假如沒有設置處置類,Java虛擬機就會在掌握台將客棧跟蹤信息打印出來,然撤退退卻出法式。
永無盡頭
Thread類還有一個和非受檢異常處置相干的辦法。這就是靜態辦法setDefaultUncaughtExceptionHandler(),該辦法可以設置法式中一切線程的非受檢異常的處置類。
當線程中拋出一個未捕捉的異常時,Java虛擬機遇從三個處所尋覓異常處置類:
起首,從線程對象中查找異常處置類,這就是我們本節所學內容。如不存在,則從線程地點的線程組(ThreadGroup)中查找異常處置類。關於這部門內容,今後會專門講授。假如照樣不存在,則查找下面方才提到的法式默許異常處置類。
假如下面提到的異常處置都不存在,則Java虛擬機將異常的客棧跟蹤信息打印到掌握台,然撤退退卻出法式。
拿來主義
本文是從 《Java 7 Concurrency Cookbook》 (D瓜哥竊譯為 《Java7並發示例集》 )翻譯而來,僅作為進修材料應用。沒有受權,不得用於任何貿易行動。
小有所成
ExceptionHandler類的完全代碼
package com.diguage.books.concurrencycookbook.chapter1.recipe8;
/**
* 非受檢異常處置類
* Date: 2013-09-22
* Time: 23:11
*/
public class ExceptionHandler 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.printf("Stack Trace: \n");
e.printStackTrace(System.out);
System.out.printf("Thread status: %s\n", t.getState());
}
}
Task類的完全代碼
package com.diguage.books.concurrencycookbook.chapter1.recipe8;
/**
* 異常生成類
* Date: 2013-09-22
* Time: 23:18
*/
public class Task implements Runnable {
@Override
public void run() {
int numero = Integer.parseInt("diguage.com");
}
}
Main類的完全代碼
package com.diguage.books.concurrencycookbook.chapter1.recipe8;
/**
* 示例的主類
* Date: 2013-09-22
* Time: 23:20
*/
public class Main {
public static void main(String[] args) {
Task task = new Task();
Thread thread = new Thread(task);
thread.setUncaughtExceptionHandler(new ExceptionHandler());
thread.start();
}
}