我想处理ThreadPoolExecutor#afterExecute()
方法中由工作线程抛出的异常。目前,我有以下代码:
public class MyExecutor extends ThreadPoolExecutor {
public static void main(String[] args) {
MyExecutor threadPool = new MyExecutor();
Task<Object> task = new Task<>();
threadPool.submit(task);
}
public MyExecutor() {
super(4, 20, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>(4000));
}
@Override
protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
System.out.println("in afterExecute()");
if (t != null) {
System.out.println("exception thrown: " + t.getMessage());
} else {
System.out.println("t == null");
}
}
private static class Task<V> implements Callable<V> {
@Override
public V call() throws Exception {
System.out.println("in call()");
throw new SQLException("testing..");
}
}
}
如果运行代码,则输出:
in call()
in afterExecute()
t == null
为什么参数
Throwable t
null
在afterExecute()
中?不应该是SQLException
实例吗? 最佳答案
这实际上是预期的行为。
引用 afterExecute
Javadoc:
这意味着throwable实例将是RuntimeException
或Error
,而不是选中的Exception
。由于SQLException
是一个已检查的异常,因此不会将其传递给afterExecute
。
这里还有其他事情(仍然引用Javadoc):
在您的示例中,由于您要提交FutureTask
,因此该任务包含在Callable
中,因此就是这种情况。即使在您更改代码以抛出RuntimeException
的情况下,如果不将其提供给afterExecute
。 Javadoc提供了用于处理此问题的示例代码,以供引用: