***特别重要,因为如果程序中使用了多线程,那么这个异常处理不好的话,无法捕捉异常,可能会导致系统奔溃,并且查询不到问题
public class CantCatchDirectly implements Runnable{
public static void main(String[] args) throws InterruptedException {
//try catch 只能捕获线程内的异常
try{
new Thread(new CantCatchDirectly(),"myThread-1").start();
Thread.sleep(300);
new Thread(new CantCatchDirectly(),"myThread-2").start();
Thread.sleep(300);
new Thread(new CantCatchDirectly(),"myThread-3").start();
Thread.sleep(300);
new Thread(new CantCatchDirectly(),"myThread-4").start();
}catch (RuntimeException e){
System.out.println("Caught Exception.");
}
}
@Override
public void run() {
try{
throw new RuntimeException();
}catch (RuntimeException e){
System.out.println("Caught Exception.");
}
}
}
以上代码运行的结果是?
按道理来说应该是Caught Exception. 遇到异常直接抛出,并且程序终止
但是结果是
Caught Exception.
Caught Exception.
Caught Exception.
Caught Exception.
所以使用多线程之后,异常一定不要随意书写
主线程可以轻松发现异常,子线程却不行
子线程异常无法用传统方式捕获
不能直接捕获的后果、提高健壮性
两个解决方案:
1.手动在每个run方法里进行try catch(不建议,因为要在每一个run方法里加,而且不知道异常的类型)
2.利用UncaughtExceptionHandler
void uncaughtException(Thread t,Throwable e)
异常处理器的调用策略
使用UncaughtExceptionHandler就能捕捉到异常
/**
* 自己的MyUncaughtExceptionHandler
*/
public class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler{
private String name;
public MyUncaughtExceptionHandler(String name) {
this.name = name;
}
@Override
public void uncaughtException(Thread t, Throwable e) {
Logger logger = Logger.getAnonymousLogger();
logger.log(Level.WARNING,"线程异常,终止啦"+t.getName(),e);
System.out.println(name+"捕获了异常"+t.getName()+"异常"+e);
}
}