在java中有两种异常:
1. Checked Exception(非运行时异常):这种异常必须在方法的throws语句中指定,或者在方法体内使用try/catch块捕获,例如: IOException和 ClassNotFoundException。
2. UncheckedException(运行时异常):这种异常由于出现的场景非常多,所以即不需要方法指定,也不需要捕获,例如:NumberFormatException。
run()方法不支持throws语句
run()方法不支持throws语句,所以当运行时异常从run()方法中抛出时,默认行为是在控制台输出堆栈记录并且退出程序。但是,使用 setUncaughtExceptionHand()方法可以捕获及处理运行时异常。
范例:1. 创建一个进程进行计算后,出现运行时异常;2. 在异常处理类中处理捕获到的运行时异常;
package com.rr.concurrent.chapter1.recipe8.test;
/**
* Created by isaac_gu on 2016/5/11.
* 1. 创建一个进程进行计算后,出现运行时异常;
*/
public class Task implements Runnable {
@Override
public void run() {
int a = 10;
int b = 0;
int c = a / b;
System.out.println("c : " + c);
}
}
异常处理:
package com.rr.concurrent.chapter1.recipe8.test;
/**
* Created by isaac_gu on 2016/5/11.
* 2. 在异常处理类中处理捕获到的运行时异常;
*/
public class MyExceptionHandler implements Thread.UncaughtExceptionHandler {
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.printf("1. %s 线程出现了异常!\n", t.getName());
System.out.printf("2. Exception: %s: %s\n", e.getClass().getName(), e.getMessage());
System.out.printf("3. Stack Trace: \n");
e.printStackTrace(System.out);
System.out.printf("4. Thread status: %s\n", t.getState());
}
}
测试类:
package com.rr.concurrent.chapter1.recipe8.test;
import java.util.concurrent.TimeUnit;
/**
* Created by isaac_gu on 2016/5/11.
* 范例:1. 创建一个进程进行计算后,出现运行时异常;2. 在异常处理类中处理捕获到的运行时异常;
*/
public class Test {
public static void main(String[] args) {
Thread thread = new Thread(new Task());
//设置异常处理类
thread.setUncaughtExceptionHandler(new MyExceptionHandler());
thread.start();
//两秒后主线程结束
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("主线程结束!");
}
}
运行结果:
1. Thread-0 线程出现了异常!
2. Exception: java.lang.ArithmeticException: / by zero
3. Stack Trace:
java.lang.ArithmeticException: / by zero
at com.rr.concurrent.chapter1.recipe8.test.Task.run(Task.java:13)
at java.lang.Thread.run(Thread.java:745)
4. Thread status: RUNNABLE
主线程结束!
Thread 类还有一个处理未捕获到的异常,静态方法 setDefaultUncaughtExcptionHandler();
当线程抛出一个异常的时候:
首先,它查找线程设置的异常处理器(UncaughtExcptionHandler );
如果没有,查找线程组(ThreadGroup)的异常处理器;
如果还找不到,将查找默认的异常处理器( DefaultUncaughtExcptionHandler );
如果没有一个处理器存在,jvm打印异常到控制台,并退出程序。