简体   繁体   English

使用Stream API或CompletableFuture的并行数据库查询?

[英]Parallel db queries using Stream API or CompletableFuture?

Assume I want to send multiple database queries (or webservice requests) in parallel, and aggregate them afterwards. 假设我要并行发送多个数据库查询(或Web服务请求),然后将它们聚合。 Would I better use the stream API or CompletableFuture ? 我是否最好使用stream API或CompletableFuture

STREAM: 流:

List<Result> result = requests.parallelStream()
                              .map(req -> query(req.getFirstname, req.getLastname))
                              .collect(toList());

//a database, or a webservice
private Result query(firstname, lastname);

FUTURES: 期货:

List<CompletableFuture> futures;
for (QueryReq req: requests) { //given input
    futures.add(CompletableFuture
                        .supplyAsync(() -> query(req.getFirstname, req.getLastname));
}

//wait for all futures to complete and collect the results
List<Result> results = new ArrayList<>();
for (CompleteableFuture f : futures) {
   results.add(f.get());
}

While stream is certainly less verbose, but which one should be preferred for what reasons? 虽然stream肯定不那么冗长,但是出于什么原因应该首选哪一个?

Sidenote : I know I could query this example easier with sql = :firstname IN (..) and ... :lastname IN(..) . 旁注 :我知道我可以使用sql = :firstname IN (..) and ... :lastname IN(..)来查询此示例。 But it's just an example about wether to use stream or futures. 但这只是关于使用流或期货的例子。

The task could as well be to send multiple webservice requests in parallel, instead of db queries. 该任务还可以是并行发送多个Web服务请求,而不是发送数据库查询。

As you already said: "stream is certainly less verbose", isn't it enough to prefer using Stream for you? 正如您已经说过的:“ stream肯定不那么冗长”,难道不愿意为您使用Stream To be fair, I think we also should rewrite the second sample code with CompletableFuture by Java 8 Stream APIs. 公平地说,我认为我们还应该使用Java 8 Stream API使用CompletableFuture重写第二个示例代码。

List<Result> result = requests.stream()
        .map(req -> CompletableFuture.supplyAsync(() -> query(req.getFirstname, req.getLastname)))
        .collect(toList()).stream()
        .map(f -> f.get()).collect(toList());

It looks it's still much verbose/longer than: 看起来它仍然比/冗长/冗长:

List<Result> result = requests.parallelStream()
        .map(req -> query(req.getFirstname, req.getLastname)).collect(toList());

However, I think here the key point is how to set the concurrent thread number: by parallel stream, the thread number is fixed by ForkJoinPool.commonPool , the CPU-core number. 但是,我认为这里的关键是如何设置并发线程号:通过并行流,线程号由CPU核心号ForkJoinPool.commonPool固定。 Usually that's too small for sending big amount web/db requests. 通常,这对于发送大量的Web / DB请求来说太小了。 For example, if there're tens/hundreds of web/db requests to send, Most times it's much faster to send the requests with 20 or more threads than the thread number defined in ForkJoinPool.commonPool . 例如,如果要发送数十/数百个web / db请求,则大多数情况下,使用20个或更多线程发送请求要比ForkJoinPool.commonPool定义的线程号快得多。 personally, I also don't know what's convenient way to specified the thread number in parallel stream. 我个人也不知道在并行流中指定线程号的简便方法。 Here are some answers you can refer to: custom-thread-pool-in-java-8-parallel-stream 您可以参考以下答案: custom-thread-pool-in-java-8-parallel-stream

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

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