我使用java 8流和并行流编写代码以获得与自定义收集器相同的功能来执行聚合功能。
当我使用htop
查看CPU使用情况时,它会显示所有用于“流”的CPU内核。和'并行流'版。因此,当使用 list.stream()时,它似乎也使用所有CPU。在这里, parallelStream()和 stream()之间在多核的使用方面的确切差异是什么?
答案 0 :(得分:44)
考虑以下计划:
import java.util.ArrayList;
import java.util.List;
public class Foo {
public static void main(String... args) {
List<Integer> list = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
list.add(i);
}
list.stream().forEach(System.out::println);
}
}
您会注意到,该程序将按照它们在列表中的顺序依次输出0到999之间的数字。如果我们将stream()
更改为parallelStream()
,则不再是这种情况(至少在我的计算机上):所有数字都是写入的,但顺序不同。所以,显然,parallelStream()
确实使用了多个线程。
htop
的原因在于,即使是单线程应用程序也被大多数现代操作系统划分为多个核心(同一个线程的部分可能在多个核心上运行,但当然不能同时运行)。因此,如果您发现某个进程使用了多个核心,则这并不一定意味着该程序必须使用多个线程。
使用多个线程时,性能也可能无法提高。同步的成本可能会增加使用多线程的收益。对于简单的测试场景,通常就是这种情况。例如,在上面的示例中,System.out
已同步。因此,尽管使用了多个线程,但实际上只能同时写入数字。
答案 1 :(得分:1)
添加到@Hoopje 的回答中:
在使用 parallelStream ()
之前,请阅读:
n
线程的简单 ExecutionService 可提供比并行流更好的性能。您还可以阅读: Java Parallel Streams Are Bad for Your Health! | JRebel by Perforce