在多线程中,如果子线程抛出了异常,在main中并不能捕获到;
看一个例子
package _Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ExceptionRunnable implements Runnable{
@Override
public void run() {
throw new RuntimeException();
}
public static void main(String[] args) {
ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
try {
newCachedThreadPool.execute(new ExceptionRunnable());
} catch (Exception e) {
System.out.println("catched exception!");
}
}
}
使用了try{}catch{}, 但是结果呢?
Exception in thread "pool-1-thread-1" java.lang.RuntimeException
at _Executors.ExceptionRannable.run(ExceptionRannable.java:10)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
可见catch并未起到作用,
多线程捕获异常要使用 UncaughtExceptionHandler 接口;
看一个简单的例子
package _Executors;
import java.lang.Thread.UncaughtExceptionHandler;
public class MyUncaughtExceptionHandler implements UncaughtExceptionHandler {
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("catched ");
}
}
接口中只有一个方法,作为抓住线程后的操作,
使用工厂模式创建线程池,将异常捕获类与线程池联系起来:
package _Executors;
import java.lang.Thread.UncaughtExceptionHandler;
import java.util.concurrent.ThreadFactory;
public class MyThreadFactory implements ThreadFactory{
private UncaughtExceptionHandler handler ;
public MyThreadFactory(UncaughtExceptionHandler handler) {
super();
this.handler = handler;
}
@Override
public Thread newThread(Runnable var1) {
Thread thread = new Thread(var1);
thread.setUncaughtExceptionHandler(handler);
return thread;
}
}
此时创建线程池时要添加工厂
package _Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ExceptionRunnable implements Runnable{
@Override
public void run() {
throw new RuntimeException();
}
public static void main(String[] args) {
MyThreadFactory myThreadFactory = new MyThreadFactory(new MyUncaughtExceptionHandler());
ExecutorService newCachedThreadPool = Executors.newCachedThreadPool(myThreadFactory );
try {
newCachedThreadPool.execute(new ExceptionRunnable());
} catch (Exception e) {
System.out.println("catched exception!");
}
}
}
之后再试一下
catched
结果执行了自定义的MyUncaughtExceptionHandler 类中的方法, 处理异常成功;
注意,以上仅仅是在执行execute方法时使用的方法,
在使用submit 操作runnable时 ,可以直接使用catch 处理异常
看一下代码
package _Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class ExceptionRunnable implements Runnable{
@Override
public void run() {
throw new RuntimeException();
}
public static void main(String[] args) {
ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
try {
Future<?> submit = newCachedThreadPool.submit(new ExceptionRunnable());
Object object = submit.get();
System.out.println(object);
} catch (Exception e) {
System.out.println("catched exception!");
}
}
}
执行结果:
catched exception!
异常是在get() 时,抛出的, 直接进行了捕获, callable 的异常捕获与此类似 ,