java 8流和并行流之间的区别
Posted
技术标签:
【中文标题】java 8流和并行流之间的区别【英文标题】:Difference between java 8 streams and parallel streams 【发布时间】:2015-10-24 11:47:42 【问题描述】:我使用 Java 8 流和并行流编写代码,以实现相同的功能,并使用自定义收集器执行聚合功能。
当我使用htop
查看 CPU 使用率时,它显示所有 CPU 内核都用于“流”和“并行流”版本。因此,似乎在使用 list.stream()
时,它也使用了所有 CPU。在这里,parallelStream()
和stream()
在多核使用方面的确切区别是什么。
【问题讨论】:
非并行流只使用一个线程来处理它们的管道。这是一个艰难的事实。除非您使用流处理进行一些显式的多线程处理,否则任何给定的终端操作都将一次在单个内核上执行。如果您提到 htop 显示所有内核的一些利用率这一事实,那可能只是由于同一线程从内核迁移到内核(未固定到单个内核)。 最好能提供您的程序代码,以便我们重现您的效果。正如 Marko 所说,list.stream()
在发出终端操作的同一线程中按顺序工作,这是 100% 的事实。但是我们无法解释为什么您观察到所有 CPU 利用率,因为我们没有看到您的代码。
请在此处找到代码 - github.com/yogirjoshi/monitortools/blob/master/src/main/java/…
我觉得这个答案可能对你有帮助:***.com/questions/23170832/…
【参考方案1】:
添加到@Hoopje 的答案:
在使用parallelStream ()
之前,请阅读:
-
它是多线程的。仅仅编写 parallelStream() 来获得并行性在 java 中几乎总是坏主意。在某些情况下它会起作用,但并非总是如此。还有其他方法可以实现并行性,而且几乎总是,在采用多线程解决方案之前您需要深思熟虑。
它使用默认的 JVM 线程池。所以,如果你在做任何阻塞操作,比如网络调用,整个java应用程序都会卡住。那是那里最大的问题。还有其他的任务分配。带有
n
线程的简单 ExecutionService 提供比并行流更好的性能。
您还可以阅读: Java Parallel Streams Are Bad for Your Health! | JRebel by Perforce
【讨论】:
【参考方案2】:考虑以下程序:
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
是同步的。因此,尽管使用了多个线程,但实际上只能同时写入数字。
【讨论】:
以上是关于java 8流和并行流之间的区别的主要内容,如果未能解决你的问题,请参考以下文章