我试图使用Java的ThreadPoolExecutor类来运行大量具有固定线程数的重载任务。每个任务都有许多地方,在此期间可能会由于异常而失败
我对ThreadPoolExecutor进行了子类化,并重写了afterExecute方法,该方法应该提供在运行任务时遇到的任何未捕获异常。然而,我似乎无法让它工作
例如:
公共类ThreadPoolErrors扩展ThreadPoolExecutor{
公共线程池错误(){
超级(1,//核心线程
1,//最大线程数
1,//超时
TimeUnit.MINUTES,//超时单位
新建LinkedBlockingQueue<;Runnable>;()//工作队列
);
}
执行后受保护的无效(可运行的r、可丢弃的t){
super.afterExecute(r,t);
如果(t!=null){
System.out.println(“出现错误:+t”);
}否则{
System.out.println(“一切正常,情况正常!”);
}
}
公共静态void main(字符串[]args){
ThreadPoolErrors threadPool=新的ThreadPoolErrors();
线程池。提交(
新的Runnable(){
公开募捐{
抛出新的RuntimeException(“哎哟!出错了。”);
}
}
);
threadPool.shutdown();
}
}
该程序的输出是“一切正常——情况正常!”,即使提交到线程池的唯一可运行程序抛出异常。这里发生了什么有线索吗
谢谢
警告:应该注意,此解决方案将阻止调用线程。
如果要处理任务引发的异常,通常最好使用Callable,而不是Runnable
Callable.call()允许抛出已检查的异常,这些异常会传播回调用线程:
可调用任务=。。。
未来=执行者提交(任务);
试一试{
future.get();
}捕获(ExecutionException ex){
例如getCause().printStackTrace();
}
如果Callable.call()引发异常,则该异常将包装在ExecutionException中,并由Future.get()引发
这可能比子类化ThreadPoolExecutor要好得多。如果异常是可恢复的,它还为您提供了重新提交任务的机会