java线程池/未来正确的方法?
我有一个WebMvc rest api。我的rest方法之一是“长时间运行的任务”。我的初始实现花费了100秒来完成测试数据
我的第二种方法是将测试数据分成多个页面,并使用线程池。在我的服务层中,我有private final ExecutorService executor = Executors.newFixedThreadPool(8);
,我用List<Future<Page>> results = this.executor.invokeAll(pages);
提交给它,这使它下降到45秒
问题是等待所有的页面。我确实需要为最终json响应准备好页面,因此我正在做:
List<Future<Page>> results = this.executor.invokeAll(pages);
for (Future<Page> result : results)
result.get();
如果我这样做,我想我真的不在乎他们完成的顺序,因为他们在原始页面列表中的顺序是正确的
但是get()是一个阻塞调用。这对webmvc rest api有影响吗
# 1 楼答案
我可以{a1}告诉你{}返回一个期货列表,其顺序与传递的可调用项相同,即传递的{}列表中的第三个{}是{}期货列表中第三个{}的来源
到目前为止,只要你是好的,你可以在之后访问这些它们中的所有将返回
true
onFuture::isDone
,没有办法使用这种方法访问中间结果您可以使用
CompletableFuture::supplyAsync(Supplier<T>, Executor)
的多个调用来获取List<CompletableFuture<T>>
,然后使用CompletableFuture::thenAccept(Consumer<T>)
在等待其他结果的同时在完成时执行操作为简洁起见,使用
String
而不是Page
的最小样本:不幸的是,创建者似乎希望在设计
CompatibleFuture
时避免使用检查异常,因此它与Callable<T>
不兼容