java 8 个流和并行流之间的区别

Difference between java 8 streams and parallel streams

我使用 Java 8 个流和并行流编写代码,以实现与自定义收集器执行聚合功能的相同功能。 当我看到 CPU 使用 htop 时,它显示所有 CPU 内核都用于 'streams' 和 'parallel streams' 版本。因此,似乎在使用 list.stream() 时,它也使用了所有 CPU。这里,parallelStream()stream()多核的使用方面的精确区别是什么

考虑以下程序:

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 是同步的。因此,实际上,尽管使用了多个线程,但同时只能写入数字。

添加到@Hoopje 的回答:

在使用 parallelStream () 之前,请阅读:

  1. 它是多线程的。在 java 中,仅仅编写 parallelStream() 来获得并行性几乎总是坏主意。在某些情况下它会起作用,但并非总是如此。还有其他方法可以实现并行性,而且几乎总是,在采用多线程解决方案之前,您需要多加考虑。
  2. 它使用默认的JVM 线程池。因此,如果您正在进行网络调用等任何阻塞操作,整个 java 应用程序可能会卡住。那是那里最大的问题。还有其他具有任务分配的。具有 n 个线程的简单 ExecutionService 提供比并行流更好的性能。

您还可以阅读: Java Parallel Streams Are Bad for Your Health! | JRebel by Perforce