java多執行緒異常的捕獲
阿新 • • 發佈:2018-12-11
在多執行緒中,如果子執行緒丟擲了異常,在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 的異常捕獲與此類似 ,