java 8 中的并行流与 Completablefuture
Parallel streams Vs Completeable Future in java 8
有什么区别:
List<String> parra = list.parallelStream()
.map(heavyPrcessingFunction)
.collect(Collectors.toList());
和这个(除了第二个有点复杂):
List<CompletableFuture<Void>> com = list.stream()
.map(x-> CompletableFuture.runAsync(() -> heavyPrcessingFunction.apply(x)))
.collect(Collectors.toList());
CompletableFuture.allOf(com.toArray(new CompletableFuture[0])).join();
// get all of strings from com now
上面的实现方式,没有区别。使用 CompletableFuture
API 的优点是,如果您想对线程进行更多控制,可以传递自定义 Executor
and/or 实现一些异步语义。
在语义上它们非常相似,主要是开销问题。
对于第二种方法,您必须为列表中的每个条目创建一个 CF,并将它们单独提交到通用 FJP。
另一方面,并行流可以通过将输入列表分成几个大片来实现,只将这些片作为任务提交到公共池,然后让一个线程基本上循环片而不是必须从其工作队列中逐个提取和展开未来。
此外,流实现意味着不仅映射操作而且收集步骤都知道并行执行,因此可以对其进行优化。
更少的分配,更少的并发数据结构上的昂贵操作,更简单的代码。
有什么区别:
List<String> parra = list.parallelStream()
.map(heavyPrcessingFunction)
.collect(Collectors.toList());
和这个(除了第二个有点复杂):
List<CompletableFuture<Void>> com = list.stream()
.map(x-> CompletableFuture.runAsync(() -> heavyPrcessingFunction.apply(x)))
.collect(Collectors.toList());
CompletableFuture.allOf(com.toArray(new CompletableFuture[0])).join();
// get all of strings from com now
上面的实现方式,没有区别。使用 CompletableFuture
API 的优点是,如果您想对线程进行更多控制,可以传递自定义 Executor
and/or 实现一些异步语义。
在语义上它们非常相似,主要是开销问题。
对于第二种方法,您必须为列表中的每个条目创建一个 CF,并将它们单独提交到通用 FJP。
另一方面,并行流可以通过将输入列表分成几个大片来实现,只将这些片作为任务提交到公共池,然后让一个线程基本上循环片而不是必须从其工作队列中逐个提取和展开未来。 此外,流实现意味着不仅映射操作而且收集步骤都知道并行执行,因此可以对其进行优化。
更少的分配,更少的并发数据结构上的昂贵操作,更简单的代码。