【发布时间】:2012-12-18 20:01:20
【问题描述】:
AFAIK 提交Callable/Runnable 到ExecutorService 是如果我想并行执行资源密集型代码的方法。因此我的方法结构:
public class ServiceClass {
protected final ExecutorService executorService = Executors.newCachedThreadPool();
public Future<Result> getResult(Object params) {
if (params == null) {
return null; // In situations like this the method should fail
}
// Do other fast pre-processing stuff
return executorService.submit(new CallProcessResult(params));
}
private class CallProcessResult implements Callable<Result> {
private Object params;
public CallProcessResult(Object params) {
this.params = params;
}
@Override
public Result call() throws Exception {
// Compute result for given params
// Failure may happen here too!
return result;
}
}
}
public class Result {
...
}
我在上面的代码中标记了两个可能发生故障的位置。对于这两种情况,可用于错误处理的选项完全不同。
在提交任务之前可能会出现参数无效、一些可能会失败的快速预处理代码等问题。
我在这里看到了几种表示失败的方式:
- 如果提供给
getResult的params无效,则立即返回null。在这种情况下,我每次调用时都必须检查getResult是否返回 null。 - 抛出已检查的异常而不是上述异常。
- 实例化一个
Future<Result>,它在get()请求上返回空值。我会用 Apache CommonsConcurrentUtils.constantFuture(null)来做到这一点。在这种情况下,我希望getResult总是返回一些非空的Future<Result>。我更喜欢这个选项,因为它与第二种情况一致。
在任务执行期间我可能会遇到严重错误,例如内存不足、文件损坏、文件不可用等。
- 我想更好的选择在我的情况是返回null,因为任务的结果是一个对象。
- 另外,我可以抛出检查异常并在
ThreadPoolExecutor.afterExecute中处理它们(如NiranjanBhat 所建议的那样)。见Handling exceptions from Java ExecutorService tasks
哪种做法更好(在这两种情况下)?
也许有其他方法可以做到这一点,或者我应该使用一种设计模式?
【问题讨论】: