java - 从 Java ExecutorService 捕获并抛出自定义异常
问题描述
我有一个函数可以遍历 HappyObjects 列表并异步设置它们的字段。在 Callable 中,可能会发生 JsonProcessingException。我必须将这个函数中的这个异常和其他异常包装到一个自定义异常(ControllerException)中,然后抛出它。
其他 Stack Overflow 帖子似乎建议收集到期货列表中并使用 get() 来捕获异常。因此,这就是我到目前为止所拥有的:
default List<HappyObj> fillfunction(final List<HappyObj> happyObjs) throws ControllerException {
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newCachedThreadPool();
List<Future<HappyObj>> futures = new ArrayList<>();
for (HappyObj happyObj : happyObjs) {
Future<HappyObj> future = executor.submit(
() -> {
final List<Mood> moods = getMoods();
for (Mood mood : moods) {
final String json = getJsonEmotion();
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
List<Emotion> emotions =
mapper.readValue(json, new TypeReference<List<Emotion>>() {}); //JsonProcessingException can occur here
MoodMetadata metadata = mood.getMoodMetadata();
if (metadata != null && metadata.getEmotionMetadata() != null) {
metadata.getEmotionMetadata().setEmotions(emotions);
}
}
happyObj.setMoods(moods);
return happyObj;
});
futures.add(future);
}
executor.shutdown();
final long maxSlaSec = 1;
try {
executor.awaitTermination(maxSlaSec, TimeUnit.SECONDS);
List<HappyObj> happyResult = new ArrayList<>();
for (Future<HappyObj> future : futures) {
happyResult.add(future.get());
}
return happyResult;
} catch (InterruptedException | ExecutionException e) {
executor.shutdownNow();
throw new ControllerException(e);
}
}
有没有比遍历List<Future>
并调用 get 来捕获 ExecutorException 更优雅的方法?我考虑过使用execute() 与 submit(),但后来我无法处理 JsonProcessingException。我看到另一个帖子建议创建一个 ThreadPoolExecutor 子类并覆盖 afterExecute(),但我无法处理 JsonProcessingException。
我问这个问题的原因之一是因为这个方法主要由 setter 组成,所以该函数最初是在操作给定的对象并返回 void。
解决方案
根据(以及的文档)ExecutionException
的文档,它已经包装了该信息。也就是说,您可以使用它来检查's body抛出的内容。Future#get
getCause
Exception
Callable
请注意,Callable#call
它本身会抛出一个Exception
... 当您从 中抛出 anException
时Callable
,它将被包装到一个ExecutionException
将从Future#get
方法中抛出的for eachCallable
中,这意味着您可以更改循环以捕获一个ExecutionException
for eachFuture
并检查它getCause
!
因此,您实际上不需要将其包装到 custom ControllerException
。
Callable
例如,您创建的s 仍然可以返回null
类型Void
,而无需对它们做任何事情。
除非场景发生变化,否则在这种情况下您不需要扩展ThreadPoolExecutor
。您甚至不必强制转换为ThreadPoolExecutor
,因为ExecutorService
接口已经具有submit
您需要的 s 。Exception
当 中出现问题时,只需从Callable
(例如JsonProcessingException
您提到的)中抛出您需要的任何东西,然后检查每个Callable
方法ExecutionException
中Future#get
的)。JsonProcessingException
有没有比遍历 List 并在每个上调用 get 来捕获 ExecutorException 更优雅的方法?
在我看来,不,没有,因为你想先提交所有Callable
s,然后让它们并行运行,最后检查它们ExecutionException
是否有任何由s 的主体Exception
抛出的(通过返回的 by )。Callable
Callable
Future#get
Future
submit
推荐阅读
- amazon-web-services - 如果没有可用的现场实例,具有 MixedInstancesPolicy 的 AWS Autoscaling 组会启动按需实例吗?
- python - python中的Opencv:如何通过管道找到一个点?
- javascript - 在 JS 中将浮点数转换为时间
- c# - 撤消和重做文档
- android - 无法在 asyncTask 中的 onPostExecute 中发送消息
- html - 无法使这个 flexbox 布局响应足够快
- java - 合并 JSON 树杰克逊
- python-3.x - webdriver.Firefox:WebDriverException:消息:“geckodriver”可执行文件需要在 PATH 中
- c# - 如何在 Azure ServiceBusTriggerAttribute 中指定具有主题/订阅的特定终结点?
- html - 如何使用 html-testRunner 报告在新行中显示已运行测试的打印文本?