【问题标题】:Advantages of parallelStream in Java SE8 [duplicate]Java SE8中parallelStream的优势[重复]
【发布时间】:2014-07-20 01:51:37
【问题描述】:

我只是在阅读一些 Java 8 代码,据我了解,您可以使用 Stream() 或 parallelStream() 迭代集合。后者的优点是使用并发将任务拆分到现代多核处理器上并加快迭代速度(尽管它不能保证结果的顺序)。

来自Oracle Java tutorial的示例代码:

double average = roster
        .stream()  /** non-parallel **/
        .filter(p -> p.getGender() == Person.Sex.MALE)
        .mapToInt(Person::getAge)
        .average()
        .getAsDouble();    

double average = roster
        .parallelStream()
        .filter(p -> p.getGender() == Person.Sex.MALE)
        .mapToInt(Person::getAge)
        .average()
        .getAsDouble();

如果我有一个集合并且我不关心它的处理顺序(即它们都有唯一的 ID 或者无论如何都是无序的或处于预排序状态),那么总是使用 parallelStream 方式是否有意义迭代一个集合?

除了我的代码在单核机器上运行时(此时我假设 JVM 会将所有工作分配给单核,因此不会破坏我的程序), 到处使用 parallelStream() 有什么缺点吗?

【问题讨论】:

    标签: java lambda java-8 java-stream


    【解决方案1】:

    如果您听 Oracle 的人谈论 Java 8 背后的设计选择,您会经常听到并行性是主要动机。并行化是 lambdas、流 API 等背后的主要驱动力。 我们来看一个流API的例子。

    private long countPrimes(int max) {
             return range(1, max).parallel().filter(this::isPrime).count();
    }
    
    private boolean isPrime(long n) {
                return n > 1 && rangeClosed(2, (long) sqrt(n)).noneMatch(divisor -> n % divisor == 0);
    } 
    

    这里我们有 countPrimes 方法,它计算 1 到最大值之间的素数个数。数字流是由 range 方法创建的。然后将流切换到并行模式,过滤掉不是素数的数字并计算剩余的数字。

    您可以看到流 API 允许我们以简洁紧凑的方式描述问题。此外,并行化只是调用 parallel() 方法的问题。当我们这样做时,流被分成多个块,每个块独立处理并在最后汇总结果。由于我们的 isPrime 方法的实现效率极低且占用大量 CPU,因此我们可以利用并行化并利用所有可用的 CPU 内核。 参考: http://java.dzone.com/articles/think-twice-using-java-8

    【讨论】:

    • 您刚刚复制并粘贴了该文章的第一部分。我在发布我的问题之前阅读了它,它没有回答我的问题,只是说一个被阻止的线程将停止整个任务。但是对于我发布的示例代码中的简单示例,这应该不是问题(即获取所有男性的平均年龄 - 这不应该阻止我的线程,除非我的应用程序正在通过网络读取数据并且有人拔出网络电缆)。
    猜你喜欢
    • 2017-05-04
    • 2015-06-22
    • 1970-01-01
    • 1970-01-01
    • 2010-11-15
    • 2017-10-25
    • 2018-07-26
    • 1970-01-01
    • 2011-09-07
    相关资源
    最近更新 更多