假设我想并行发送多个数据库查询(或Web服务请求),然后再聚合它们。我会更好地使用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);
期货:
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());
}
虽然stream肯定不那么冗长,但出于什么原因应该首选哪一个?
Sidenote :我知道我可以使用sql = :firstname IN (..) and ... :lastname IN(..)
更轻松地查询此示例。但它只是一个关于使用流或期货的例子。
任务也可以是并行发送多个Web服务请求,而不是数据库查询。
答案 0 :(得分:1)
正如您已经说过的那样:“流量肯定不那么冗长”,是不是更愿意为您使用create-react-app
?公平地说,我认为我们也应该用Java 8 Stream API用Stream
重写第二个示例代码。
CompletableFuture
它看起来仍然比以下更加冗长/更长:
List<Result> result = requests.stream()
.map(req -> CompletableFuture.supplyAsync(() -> query(req.getFirstname, req.getLastname)))
.collect(toList()).stream()
.map(f -> f.get()).collect(toList());
但是,我认为这里的关键点是如何设置并发线程数:通过并行流,线程数由ForkJoinPool.commonPool
固定,CPU核心数。通常,这对于发送大量Web / db请求来说太小了。例如,如果要发送数十/数百个web / db请求,则大多数情况下发送具有20个或更多线程的请求要比List<Result> result = requests.parallelStream()
.map(req -> query(req.getFirstname, req.getLastname)).collect(toList());
中定义的线程数快得多。就个人而言,我也不知道在并行流中指定线程号的方便方法。以下是您可以参考的一些答案:custom-thread-pool-in-java-8-parallel-stream