gpt4 book ai didi

java - 并发 - foreach 循环中的非阻塞设计

转载 作者:行者123 更新时间:2023-11-30 05:50:53 26 4
gpt4 key购买 nike

我正在开发一项返回 List<Response> 的服务目的。

有两种对象可以构建响应。其中一个从内部数据填充内容,另一个接触服务并获取数据。

for(Item item : items){
if(item is external){
call service and get result and populate Response and add to List
}

if(item is internal)
{
populate response object and add to list
}
}

当前的 impl 是程序化的和阻塞的,我想要的是一个非阻塞设计,这样,如果该项目是外部的,则触发调用并继续列表中的下一个项目。然后当循环完成时,我可以等待所有完成。

执行此操作的好方法是什么?我也在考虑为每个职责创建单独的类。

编辑:引入的原因是为了减少延迟命中。

最佳答案

ExecutorCompletionService (带有记住提交任务的回调的线程池)看起来像一个 git 错误:

CompletionService<Response> executorService = 
new ExecutorCompletionService<>(Executors.newFixedThreadPool(10));
int totalExternal = 0;

for(Item item : items){
if(item is external){
executorService.submit(externalCall(item));
++totalExternal;
}

if(item is internal){
populate response object and add to list
}
}

for (int i = 0; i < totalExternal; ++totalExternal) {
addAsynchResultToResponseList(executorService.take().get());
}

在哪里externalCall(item)为清楚起见,定义如下:

Callable<Response> externalCall(Item item) {
return new Callable<Response>() {
//...
}
}

很明显,一旦您采用异步方式,结果列表就可以具有任意顺序。


另一种方法是使用普通的 ExecutorService并有一个中间体 List<Future<Response>> .诀窍是使用 AsyncResult 包装内部响应的包装器(它创建 Future 立即完成并返回传递的值)。

List<Future<Response>> futures = new ArrayList<>();
for(Item item : items){
if(item is external){
futures.add(executorService.submit(externalCall(item)));
}

if(item is internal){
futures.add(new AsyncResult(synchResponse));
}
}

现在您可以简单地遍历 futures . AsyncResult将立即返回,因为该值在创建时已经是计算机 ( synchResponse )。但是你将不得不等待 Future s 从线程池返回。

记住 Future.get()允许您检索原始异常。同样是Future的顺序列表中的 s 与原始项目的顺序相同,因此如果第 n 个 Future失败,items 中的第 n 项列表是原因。

关于java - 并发 - foreach 循环中的非阻塞设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13500670/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com