有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java 8流和并行流之间的多线程差异

我使用Java8流和并行流编写了代码,用于使用自定义收集器执行聚合功能的相同功能。 当我使用htop查看CPU使用情况时,它显示了所有CPU核心都用于“流”和“并行流”版本。因此,当使用list.stream()时,它似乎也使用所有CPU。这里,就多核的使用而言,{}和{}之间的确切区别是什么


共 (2) 个答案

  1. # 1 楼答案

    考虑以下程序:

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

  2. # 2 楼答案

    在@Hoopje的回答中添加:

    在使用parallelStream ()之前,请阅读以下内容:

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

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