我们都知道在线程在出现异常的时候,这条线程会终止。而在多线程环境下,是无法用传统方法来捕获子线程的异常,也就是说无法处理,现在我们来模拟一下这种情况
public class Test7 implements Runnable {
public static void main(String[] args) throws InterruptedException {
Test7 test7 = new Test7();
try {
new Thread(test7,"线程-1").start();
Thread.sleep(200);
new Thread(test7,"线程-2").start();
Thread.sleep(200);
new Thread(test7,"线程-3").start();
Thread.sleep(200);
new Thread(test7,"线程-4").start();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
System.out.println("捕获到子线程异常");
}
}
@Override
public void run() {
// TODO Auto-generated method stub
throw new RuntimeException(); //模拟一个RuntimeException异常
}
}
运行结果:
并没有打印出我们期望的 catch语句块的内容。
针对这种无法捕获子线程异常的情况,有两种方法
第一种方法:
1.在run方法里面用 try catch 捕获 ,这种方法虽然可行 ,但是每个run方法都要写一遍,并且有可能还不知道线程具体抛出的异常类型。 这种方式简单就不在演示了。
第二种方法:
2.使用Thread类的UncaughtExceptionHandler
public class Test7 implements Runnable {
public static void main(String[] args) throws InterruptedException {
Thread.setDefaultUncaughtExceptionHandler(new MyUncaughtExceptionHandler("捕获器1"));
Test7 test7 = new Test7();
new Thread(test7,"线程-1").start();
Thread.sleep(200);
new Thread(test7,"线程-2").start();
Thread.sleep(200);
new Thread(test7,"线程-3").start();
Thread.sleep(200);
new Thread(test7,"线程-4").start();
}
@Override
public void run() {
// TODO Auto-generated method stub
throw new RuntimeException();
}
}
class MyUncaughtExceptionHandler implements UncaughtExceptionHandler {
private String name;
public MyUncaughtExceptionHandler(String name) {
this.name = name;
}
@Override
public void uncaughtException(Thread t, Throwable e) {
// TODO Auto-generated method stub
Logger logger = Logger.getAnonymousLogger();
logger.log(Level.WARNING,"线程异常",e);
System.out.println(name+"捕获了"+t.getName()+"异常:"+e);
}
}
运行结果: