我使用Java 8流和并行流编写了具有相同功能的代码,并使用了自定义收集器来执行聚合功能。
当我使用htop
查看CPU使用率时,它显示所有用于“流”和“并行流”版本的CPU内核。因此,似乎在使用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
的解释是,大多数现代操作系统甚至将多线程内核划分为单线程应用程序(同一线程的部分可能在多个内核上运行,但当然不能同时运行)。因此,如果您看到一个进程使用了多个内核,则并不一定意味着该程序使用了多个线程。同样,使用多个线程时,性能可能不会提高。同步的成本可能会限制使用多个线程的 yield 。对于简单的测试场景,通常是这种情况。例如,在上面的示例中,
System.out
是同步的。因此,尽管使用了多个线程,但实际上只能同时写入数字。