简体   繁体   English

Java 8使用CompletableFuture :: join维护流顺序

[英]Java 8 maintain stream order with CompletableFuture::join

I have an input stream of queries which are getting executed asynchronously. 我有一个查询的输入流,它们正在异步执行。 I want to make sure that when I use Completablefuture::join , the result of those requires are collected int the order of input query stream. 我想确保在使用Completablefuture::join ,将这些需求的结果按输入查询流的顺序收集到。

This is how my code looks like: 这是我的代码的样子:

queries.stream()
     .map(query -> CompletableFuture.supplyAsync(() -> {
                    try {
                        return SQLQueryEngine.execute(query);
                    } catch (InternalErrorException e) {
                        throw new RuntimeException(e);
                    }
     }))
     .map(CompletableFuture::join)
     .collect(Collectors.toList());

SQLQueryEngine.execute(query); SQLQueryEngine.execute(查询); returns a List<Results> so output is List<List<Result> . 返回List<Results>因此输出为List<List<Result> I want to flatten and combine all the results into one single List. 我想拼合并将所有结果合并到一个列表中。 If i use .flatMap(List::stream) before collection to flatten, will it maintain the ordering? 如果我在集合进行展平之前使用.flatMap(List :: stream),它将保持排序吗?

You probably meant .flatMap and yes, it will retain the ordering. 您可能是说.flatMap ,是的,它将保留顺序。

Consider explicitly passing an Executor to supplyAsync to avoid scheduling your IO-bound sql queries in ForkJoinPool.commonPool() . 考虑将Executor显式传递给supplyAsync以避免在ForkJoinPool.commonPool()安排与IO绑定的sql查询。

As @Ruben pointed out , you are joining each task in the current thread immediately after submitting it and before submitting the next query, which is likely a bug. 正如@Ruben 指出的那样 ,您将在提交每个任务之后并提交下一个查询之前立即将每个任务加入当前线程中,这可能是一个错误。 You should submit all queries first and only then start joining. 您应该先提交所有查询,然后才可以开始加入。

You can do it like this (with static import of toList ): 您可以这样做(使用toList静态导入):

queries.stream()
    .map(query -> CompletableFuture.supplyAsync(...))
    .collect(toList())
    .stream()
    .map(CompletableFuture::join)
    .collect(toList());

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

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