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

时间:2015-08-02 06:29:05

标签: java multithreading java-8 multicore

我使用java 8流和并行流编写代码以获得与自定义收集器相同的功能来执行聚合功能。 当我使用htop查看CPU使用情况时,它会显示所有用于“流”的CPU内核。和'并行流'版。因此,当使用 list.stream()时,它似乎也使用所有CPU。在这里, parallelStream() stream()之间在多核的使用方面的确切差异是什么?

2 个答案:

答案 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 () 之前,请阅读:

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

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