简体   繁体   English

获得可完成未来的结果

[英]Get result of completablefuture

I am using completablefuture to be returned from an async thread in springboot application.我正在使用 completablefuture 从 springboot 应用程序中的异步线程返回。 My implementation is below.我的实现如下。 From my understanding a new thread should be started for each item in list and should process parallely.根据我的理解,应该为列表中的每个项目启动一个新线程,并且应该并行处理。 I understand .get will block the execution but as it is parallely running still i dont see any improvement in performance.我知道 .get 会阻止执行,但由于它是并行运行的,我仍然没有看到性能有任何改善。 Any suggestions on below please to improve the performance?请在下面提出任何建议以提高性能?

ServiceA.java服务A.java

@Autowired
ServiceB serviceb;


public List<String> getNames(List<Item> items) {
List<CompletableFuture<String>> list = new ArrayList<>();
List<String> returnList = new ArrayList<>();
for( Item item: items) {
  CompletableFuture<String> getItemName = serviceb.doProcess(item);
  list.add(getItemName):
}

for( CompletableFuture name : list) {
 returnList.add(name.get());
}
return returnList;
}

ServiceB.java服务B.java

Class ServiceB {
@Async
Public CompletableFuture<String> doProcess(Item item)
{
   //do process
}

You could call allOf to wait for all results.您可以调用allOf来等待所有结果。 This will wait for all CompletableFuture to complete.这将等待所有 CompletableFuture 完成。

        List<String> returnList = new ArrayList<>(items.size());
        CompletableFuture<String>[] tasks = items.stream()
            .map(value-> serviceb.doProcess(value).thenApply(returnList::add))
            .toArray(CompletableFuture[]::new);
        // wait for all tasks to finish
        CompletableFuture.allOf(tasks).get(50, TimeUnit.SECONDS);
        // return the results
        return returnList;

Second solution would be to use an reactive approach like publisher/subscriber pattern ( Spring WebFlux or JavaRx ).第二种解决方案是使用响应式方法,如发布者/订阅者模式( Spring WebFluxJavaRx )。 This way your application would have little/no waiting operation.这样,您的应用程序将很少/没有等待操作。 But this would affect your application architecture.但这会影响您的应用程序架构。

One Advice : In order to create an CompletableFuture use the constructor with ExecutorService in order to keep in check number of threads and have control over running threads or when application shuts down.一个建议:为了创建CompletableFuture使用带有ExecutorService的构造函数来检查线程数并控制正在运行的线程或应用程序何时关闭。

The get() will definitely not going to work out as it will block the main thread of execution to fetch the result from the async threads. get() 肯定不会成功,因为它会阻止主执行线程从异步线程获取结果。 A better option would be to use callback methods(thenApply() etc) accordingly so as to let the main thread continue its work.更好的选择是相应地使用回调方法(thenApply() 等),以便让主线程继续工作。

You can use thenAccept to add the items to the list.您可以使用thenAccept将项目添加到列表中。

List<String> list = new CopyOnWriteArrayList<>();
CompletableFuture.allOf(
    Stream.of(items).map(
        i -> CompletableFuture.supplyAsync(i).thenAccept(list::add)
    ).toArray(CompletableFuture[]::new)
).get(10, SECONDS);

return list;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM