我有一个接受新任务的执行者服务:
ExecutorService executor = Executors.newFixedThreadPool(1000);
//stupid example with several parralel tasks
for (int i = 0; i < 1000; i++) {
try{
Runnable task = new Runnable() {
public void run() {
throw new RuntimeException("foo");
}
};
executor.submit(task);
}
catch (ExecutionException e) {
System.out.println(e.getMessage());
}
}
我的问题是我无法捕获Runnable引发的任何异常,除非我这样做:
Future<?> future = executor.submit(task);
try {
future.get();
} catch (Exception e) {
System.out.println("############### exception :" + e.getMessage());
}
问题是future.get()是阻塞的,所以如果我无法异步运行我的任务而且我的任务不会并行运行,而是顺序运行。
我希望能够使用Java 8和CompletableFuture,但我不能...... 你还有其他想法吗?
由于
答案 0 :(得分:3)
Runnable中的代码在单独的线程上执行,因此您必须在run()
方法中处理其异常。
如果您需要收集所有异常以供以后处理,我会这样做:
ExecutorService executor = Executors.newFixedThreadPool(1000);
final List<Exception> exceptions = // a place to put exceptions
Collections.synchronizedList(new ArrayList<Exception>());
for (int i = 0; i < 1000; i++) {
Runnable task = new Runnable() {
public void run() {
try {
throw new RuntimeException("foo");
} catch (Exception e) {
exceptions.add(e); // save the exception for later
}
}
};
executor.submit(task);
}
// wait for all the tasks to finish, then...
for (Exception e: exceptions) {
// whatever you want to do
}
否则,如果您只想获取有关每个异常的信息:
Runnable task = new Runnable() {
public void run() {
try {
throw new RuntimeException("foo");
} catch (Exception e) {
e.printStackTrace();
}
}
};
答案 1 :(得分:1)
异步执行任务后您需要执行的任何操作都可以添加到任务本身。
for (int i = 0; i < 1000; i++) {
final Runnable task = new Runnable() {
public void run() {
throw new RuntimeException("foo");
}
};
executor.submit(new Runnable() {
public void run() {
try {
task.run();
} catch (Throwable e) {
e.printStackTrace();
}
}
});
}
或者将它们组合成一个Runnable。
答案 2 :(得分:0)
这可能不是最佳解决方案,但我们可以创建一个父Runnable,它将完成实际Runnable的工作。父母将捕获您需要了解的所有例外情况。这是一种轻微的错综复杂的方法:
public static void main(String[] args){
ExecutorService executor = Executors.newFixedThreadPool(1000);
//stupid example with several parralel tasks
for (int i = 0; i < 5; i++) {
Runnable task = new Runnable() {
public void run() {
throw new RuntimeException("foo");
}
};
ParentRunnable t = new ParentRunnable();
t.setRunnable(task, i);
executor.submit(t);
}
}
static class ParentRunnable implements Runnable {
Runnable r;
int index;
public void setRunnable(Runnable r, int index){
this.r = r;
this.index = index;
}
public void run() {
try{
System.out.println("\n" + index + "\n");
r.run();
}catch(Exception e){
e.printStackTrace();
}
}
}