[英]Process List of entities using completable futures
I have a list of entities of type T
. 我有一个类型为
T
的实体的列表。 I also have a functional interface which acts as Supplier
which has the method to performTask
on entity and send back the result R
which looks like: 我也有一个充当
Supplier
的功能接口,该接口具有对实体执行performTask
并将结果R
发送回的方法,如下所示:
R performTask(T entity) throws Exception
. R performTask(T entity) throws Exception
。
I want to filter both: the successful results and errors & exceptions coming out of it onto separate maps. 我想同时过滤:成功的结果和错误和异常都过滤到单独的地图上。 The code I wrote here is taking time, Kindly suggest what can be done.
我在这里编写的代码花费时间,请提出可以做什么的建议。
I am looping on the list of entities, then process their completable future one by one, which I think is not the right way to do. 我浏览了实体列表,然后逐个处理它们的可完成未来,我认为这不是正确的方法。 Can you all suggest what can be done here ?
大家可以建议在这里可以做什么吗?
private void updateResultAndExceptionMaps(List < T > entities, final TaskProcessor < T, R > taskProcessor) {
ExecutorService executor = createExecutorService();
Map < T, R > outputMap = Collections.synchronizedMap(new HashMap < T, R > ());
Map < T, Exception > errorMap = new ConcurrentHashMap < T, Exception > ();
try {
entities.stream()
.forEach(entity -> CompletableFuture.supplyAsync(() -> {
try {
return taskProcessor.performTask(entity);
} catch (Exception e) {
errorMap.put(entity, (Exception) e.getCause());
LOG.error("Error processing entity Exception: " + entity, e);
}
return null;
}, executor)
.exceptionally(throwable -> {
errorMap.put(entity, (Exception) throwable);
LOG.error("Error processing entity Throwable: " + entity, throwable);
return null;
})
.thenAcceptAsync(R -> outputMap.put(entity, R))
.join()
); // end of for-each
LOG.info("outputMap Map -> " + outputMap);
LOG.info("errorMap Map -> " + errorMap);
} catch (Exception ex) {
LOG.warn("Error: " + ex, ex);
} finally {
executor.shutdown();
}
}
outputmap
should contain the entity and result, R
. outputmap
应该包含实体和结果R
errorMap
should contain entity and Exception
. errorMap
应该包含Entity和Exception
。
This is because you iterate over List
of entities one by one, create CompletableFuture
object and immediately block iteration because of join
method which waits until given processor finishes it work or throw exception. 这是因为您要逐一遍历实体
List
,创建CompletableFuture
对象,并由于join
方法而立即阻止迭代,因为join
方法要等到给定处理器完成其工作或引发异常。 You can do that with full multithreading support by converting each entity to CompletableFuture
, collect all CompletableFuture
instances and after that wait for all invoking join
on each. 您可以通过每个实体转换为做到这一点与完全支持多线程
CompletableFuture
,收集所有CompletableFuture
实例,之后等待所有调用join
每个。
Below code should do the trick in your case: 下面的代码可以解决您的问题:
entities.stream()
.map(entity -> CompletableFuture.supplyAsync(() -> {
try {
return taskProcessor.performTask(entity);
} catch (Exception e) {
errorMap.put(entity, (Exception) e.getCause());
}
return null;
}, executor)
.exceptionally(throwable -> {
errorMap.put(entity, (Exception) throwable);
return null;
})
.thenAcceptAsync(R -> outputMap.put(entity, R))
).collect(Collectors.toList())
.forEach(CompletableFuture::join);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.