从Java ExecutorService捕获线程异常 [英] Catching thread exceptions from Java ExecutorService
问题描述
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class TestThreadFailure {
public static void main(String [] args){
int size = 1;
ExecutorService exec = Executors.newFixedThreadPool(size);
ThreadFailTask worker = new ThreadFailTask();
未来<整数> result = exec.submit(worker);
try {
整数值= result.get();
System.out.println(Result:+ value);
} catch(Throwable t){
System.out.println(Caught failure:+ t.toString());
exec.shutdownNow();
System.out.println(Stack Trace:);
t.printStackTrace();
返回;
}
抛出新的RuntimeException(没有抓到失败!!);
}
public static class ThreadFailTask implements Callable< Integer> {
@Override
public Integer call(){
int nbuf = 65536;
double [] [] buf = new double [nbuf] [nbuf];
return new Integer((int)buf [0] [0]);
}
}
}
我不相信当使用 submit()
时,有一个标准的钩子来获取这些异常。但是,如果您需要支持 submit()
(这听起来很合理,鉴于您使用 Callable
),您可以随时包装Callable和Runnable:
ExecutorService executor = new ThreadPoolExecutor(1,10,60,TimeUnit.SECONDS,new LinkedBlockingDeque< ; Runnable>()){
@Override
public< T>未来< T>提交(最终可调用< T>任务){
可调用< T> wrappedTask = new Callable< T>(){
@Override
public T call()throws异常{
try {
return task.call();
}
catch(异常e){
System.out.println(哦,男孩,有东西破了!);
e.printStackTrace();
throw e;
}
}
};
返回super.submit(wrappedTask);
}
};
当然,这个方法只有在你建立 ExecutorService
首先。此外,请记住覆盖所有三个 submit()
变体。
I'm working on a software development framework for parallel computing JavaSeis.org. I need a robust mechanism for reporting thread exceptions. During development, knowing where exceptions came from has high value, so I would like to err on the side of over-reporting. I would also like to be able to handle Junit4 testing in threads as well. Is the approach below reasonable or is there a better way ?
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class TestThreadFailure {
public static void main(String[] args) {
int size = 1;
ExecutorService exec = Executors.newFixedThreadPool(size);
ThreadFailTask worker = new ThreadFailTask();
Future<Integer> result = exec.submit(worker);
try {
Integer value = result.get();
System.out.println("Result: " + value);
} catch (Throwable t) {
System.out.println("Caught failure: " + t.toString());
exec.shutdownNow();
System.out.println("Stack Trace:");
t.printStackTrace();
return;
}
throw new RuntimeException("Did not catch failure !!");
}
public static class ThreadFailTask implements Callable<Integer> {
@Override
public Integer call() {
int nbuf = 65536;
double[][] buf = new double[nbuf][nbuf];
return new Integer((int) buf[0][0]);
}
}
}
I don't believe there is a standard 'hook' to get to these exceptions when using submit()
. However, if you need to support submit()
(which sounds reasonable, given that you use a Callable
), you can always wrap the Callables and Runnables :
ExecutorService executor = new ThreadPoolExecutor(1, 10, 60, TimeUnit.SECONDS, new LinkedBlockingDeque<Runnable>()) {
@Override
public <T> Future<T> submit(final Callable<T> task) {
Callable<T> wrappedTask = new Callable<T>() {
@Override
public T call() throws Exception {
try {
return task.call();
}
catch (Exception e) {
System.out.println("Oh boy, something broke!");
e.printStackTrace();
throw e;
}
}
};
return super.submit(wrappedTask);
}
};
Of course, this method only works if you're the one building the ExecutorService
in the first place. Furthermore, remember to override all three submit()
variants.
这篇关于从Java ExecutorService捕获线程异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!