Java8中并行化流parallel的使用

生活中,最使人疲惫的往往不是道路的遥远,而是心中的郁闷;最使人痛苦的往往不是生活的不幸,而是希望的破灭;最使人颓废的往往不是前途的坎坷,而是自信的丧失;最使人绝望的往往不是挫折的打击,而是心灵的死亡。所以我们要有自己的梦想,让梦想的星光指引着我们走出落漠,走出惆怅,带着我们走进自己的理想。

导读:本篇文章讲解 Java8中并行化流parallel的使用,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

场景

Java8新特性-Stream对集合进行操作的常用API:

Java8新特性-Stream对集合进行操作的常用API_霸道流氓气质的博客-CSDN博客_javalist.stream

前面讲Stream的常用api的使用,在处理一些集合数据时很方便,但是在执行一些耗时或是占用资源很高的任务的

时候,串行化的流无法带来速度/性能上的提升,除了使用多线程来并行执行任务之外,Stream中也提供了这样的方法。

parallelStream()方法或者是使用stream().parallel()来转化为并行流。

并行和并发

1、并发是两个任务共享时间段,并行是两个任务在同一时间发生,比如运行在多核CPU上。

如果一个程序要运行两个任务并且只有一个CPU给它们分配了不同的时间片,那么这就是并发,而不是并行。

Java8中并行化流parallel的使用

 

2、并行化是指为缩短任务执行时间,将一个任务分解成几个部分,然后并行执行。这和顺序执行的任务量是一样的,区别就是

用更多的马来拉车,花费的时间自然少。实际上,和顺序执行相比,并行化执行任务时,CPU承载的工作量更大。

3、数据并行化是指将数据分成块,为每块数据分配单独的数据单元,就像从车里取出一些货物,放到另一辆车上,两辆马车

都沿着同样的路径到达目的地。

4、当需要在大量数据上执行同样的操作时,数据并行化很管用。它将问题分解成可以在多块数据上求解的形式,然后对每块数据执行运算,

最后将各数据块上得到的结果汇总,从而获得答案。

5、任务并行化与数据并行化不同,在任务并行化中,线程不同,工作各异,每个线程不光可以为不同用户服务,还可以为同一个用户执行不同的任务。

并行化流

并行化操作流只需要改变一个方法调用。如果已经有Stream对象,调用它的parallel方法就可以。如果想要从一个集合类创建一个流,调用

parrallelStream能获取。

看一个具体例子

Java8中并行化流parallel的使用

 

但是并行化运行流不一定比串行化运行更快。

以上面的例子为例,在一个四核电脑上,如果有10张专辑,串行化代码的速度是并行化代码速度的8倍;

如果将专辑数量增至100张,串行化和并行化速度相当;

如果将专辑数量增至10000张,则并行化代码的速度是串行化速度的2.5倍。

注:

博客:
霸道流氓气质的博客_CSDN博客-C#,架构之路,SpringBoot领域博主
关注公众号
霸道的程序猿
获取编程相关电子书、教程推送与免费下载。

实现

1、下面拿一个简单的例子测试下

统计1到某个范围内的所有质数的数量

package com.ruoyi.demo.java8demo;

import java.time.Duration;
import java.time.Instant;
import java.util.stream.IntStream;

public class parallelDemo {
    public static void main(String[] args) {

        Instant begin = Instant.now();
        //串行操作
        //long count = IntStream.range(1, 1000000).filter(parallelDemo::isPrime).count();//404
        //并行操作
        //long count1 = IntStream.range(1, 1000000).parallel().filter(parallelDemo::isPrime).count();//166
        //串行操作
        //long count = IntStream.range(1, 100000).filter(parallelDemo::isPrime).count();//62
        //并行操作
        long count1 = IntStream.range(1, 100000).parallel().filter(parallelDemo::isPrime).count();//72
        Instant end = Instant.now();
        System.out.println("耗时:"+ Duration.between(begin, end).toMillis());
    }

    private static boolean isPrime(int number){
        int x = number;
        if(x<2){
            return  false;
        }
        for(int i =2;i<Math.sqrt(x);++i){
            if(x % i == 0){
                return  false;
            }
        }
        return true;
    }
}

后面跟的是不同数量下的耗时,可以发现并行化不一定比串行化速度快。

2、影响性能因素

数据大小

输入数据的大小会影响并行化处理对性能的提升。将问题分解之后并行化处理,再将结果合并会带来额外的开销。因此

只有数据足够大、每个数据处理管道花费的时间足够多,并行化处理采用意义。

元数据结构

每个管道的操作都基于一些初始化数据源,通常是集合。将不同的数据源分割相对容易,这里的开销影响了在管道并行处理数据时到底能带来

多少性能上的提升。

装箱

处理基本类型比处理装箱类型要快。

核的数量

极端情况下,只有一个核,因此完全没必要并行化。拥有的核越多,获得潜在性能提升的幅度越大。在实践中,核的数量不单指你的机器上有多少核,

更是指运行时你的机器能使用多少核。也就是说同行运行的其他进程,或者线程关联性会影响性能。

单元处理开销

比如数据大小,这是一场并行执行花费时间和分解合并操作开销之间的战争。花在流中每个元素身上的时间越长,并行操作带来的性能提升越明显。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/135890.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!