Java8的Stream()与ParallelStream()的区别说明

 更新时间:2021年07月28日 10:11:35   作者:No8g攻城狮  
这篇文章主要介绍了Java8的Stream()与ParallelStream()的区别说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

Java8 Stream()与ParallelStream()区别

Stream

无状态:指元素的处理不受之前元素的影响;

有状态:指该操作只有拿到所有元素之后才能继续下去。

非短路操作:指必须处理所有元素才能得到最终结果;

短路操作:指遇到某些符合条件的元素就可以得到最终结果,如 A || B,只要A为true,则无需判断B的结果。

ParallelStream

对于ParallelStream,需要知道的是里面的执行是异步的,并且使用的线程池是ForkJoinPool.common,可以通过设置-Djava.util.concurrent.ForkJoinPool.common.parallelism = N来调整线程池的大小;

ParallelStream的作用

Stream具有平行处理能力,处理的过程会分而治之,也就是将一个大任务切分成多个小任务,这表示每个任务都是一个操作,因此像以下的程式片段:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9); 
numbers.parallelStream().forEach(System.out::println);

得到的展示顺序不一定会是1、2、3、4、5、6、7、8、9,而可能是任意的顺序。得到的结论就是parallelStream()每次执行的结果都不相同,与多线程程序中执行的结果类似。如果希望最后顺序是按照原来Stream的数据顺序,那可以调用forEachOrdered()。

例如:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9); 
numbers.parallelStream().forEachOrdered(System.out::println);

你得到的展示顺序就是1、2、3、4、5、6、7、8、9。

Java8并行流parallelStream()和stream()的区别就是支持并行执行,提高程序运行效率。但是如果使用不当可能会发生线程安全的问题。

其他同类知识点:

1、Java集合Stream类filter的使用;

2、Java中的排序问题(Java8新特性 stream流、stream多字段排序);

parallelStream与stream效率比较

结论

parallel线程不安全

parallel的效率,因为是多线程,默认线程数量是计算器处理器的数量

代码

public class StreamTest {
    @Test
    public void streamVs(){
        List<Integer> list1 = new ArrayList<>(10000);
        List<Integer> list2 = new ArrayList<>(10000);
        List<Integer> list3 = new ArrayList<>(10000);
        Lock lock = new ReentrantLock();
        IntStream.range(0, 10000).forEach(list1::add);
        IntStream.range(0, 10000).parallel().forEach(list2::add);
        IntStream.range(0, 10000).parallel().forEach(i -> {
            lock.lock();
            try {
                list3.add(i);
            }finally {
                lock.unlock();
            }
        });
        System.out.println("串行执行的大小:" + list1.size());
        System.out.println("并行执行的大小:" + list2.size());
        System.out.println("加锁并行执行的大小:" + list3.size());
    }
    @Test
    public void streamVs2(){
        List<Person> persons = constructPersons();
        doFor(persons);
        doStream(persons);
        doParallelStream(persons);
    }
    /**
     * 构造数据
     *
     * @return
     */
    public List<Person> constructPersons() {
        List<Person> persons = new ArrayList<Person>();
        for (int i = 0; i < 5; i++) {
            Person p = new Person(i, "name" + i, "sex" + i, i);
            persons.add(p);
        }
        return persons;
    }
    /**
     * for
     *
     * @param persons
     */
    public void doFor(List<Person> persons) {
        long start = System.currentTimeMillis();
        for (Person p : persons) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
            }
            //System.out.println(p.name);
        }
        long end = System.currentTimeMillis();
        System.out.println("doFor cost:" + (end - start));
    }
    /**
     * 顺序流
     *
     * @param persons
     */
    public void doStream(List<Person> persons) {
        long start = System.currentTimeMillis();
        persons.stream().forEach(x -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
            }
            //System.out.println(x.name);
        });
        long end = System.currentTimeMillis();
        System.out.println("doStream cost:" + (end - start));
    }
    /**
     * 并行流
     *
     * @param persons
     */
    public void doParallelStream(List<Person> persons) {
        long start = System.currentTimeMillis();
        persons.parallelStream().forEach(x -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
            }
            //System.out.println(x.name);
        });
        long end = System.currentTimeMillis();
        System.out.println("doParallelStream cost:" + (end - start));
    }
}
class Person {
    int    id;
    String name;
    String sex;
    float  height;
    public Person(int id, String name, String sex, float height) {
        this.id = id;
        this.name = name;
        this.sex = sex;
        this.height = height;
    }
}

测试截图

串行执行的大小:10000

并行执行的大小:7219

加锁并行执行的大小:10000

doFor cost:5012
doStream cost:5073
doParallelStream cost:2013

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Automapper实现自动映射的实例代码

    Automapper实现自动映射的实例代码

    这篇文章主要介绍了Automapper实现自动映射的实例代码,需要的朋友可以参考下
    2017-09-09
  • java开源调度如何给xxljob加k8s执行器

    java开源调度如何给xxljob加k8s执行器

    这篇文章主要介绍了java开源调度如何给xxljob加一个k8s执行器, xxljob 在设计上,抽象出了执行器的接口,所以实现一个语言的执行器并不复杂,这里主要探索下,如何利用k8s的pod 的能力,使用 xxljob 调度 pod 运行,实现一个通用的和语言无关的执行器
    2022-02-02
  • Mybatis初始化知识小结

    Mybatis初始化知识小结

    Mybatis的初始化过程就是加载自己运行时所需要的配置信息的过程,这篇文章主要介绍了Mybatis初始化知识小结,需要的朋友可以参考下
    2021-10-10
  • java数据结构与算法之马踏棋盘

    java数据结构与算法之马踏棋盘

    这篇文章主要为大家详细介绍了java数据结构与算法之马踏棋盘,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • java JDBC主要组件连接数据库及执行SQL过程示例全面详解

    java JDBC主要组件连接数据库及执行SQL过程示例全面详解

    这篇文章主要为大家介绍了java JDBC主要组件连接数据库及执行SQL的过程示例全面详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-06-06
  • 详解springmvc如何处理接受http请求

    详解springmvc如何处理接受http请求

    这篇文章主要给大家介绍了springmvc如何处理接受http请求,文中通过代码示例给大家讲解的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下
    2024-02-02
  • SpringBoot接口加密解密统一处理

    SpringBoot接口加密解密统一处理

    这篇文章主要为大家详细介绍了SpringBoot接口加密解密统一处理,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-08-08
  • Java文件、文件夹权限修改的两种方法

    Java文件、文件夹权限修改的两种方法

    这篇文章主要给大家介绍了关于Java文件、文件夹权限修改的两种方法,文中通过示例代码介绍的非常详细,对大家学习或者使用Java具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-08-08
  • springboot使用Logback把日志输出到控制台或输出到文件

    springboot使用Logback把日志输出到控制台或输出到文件

    这篇文章给大家介绍springboot项目使用日志工具Logback把日志不仅输出到控制台,也可以输出到文件的操作方法,本文通过实例图文相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2020-10-10
  • springBoot基于webSocket实现扫码登录

    springBoot基于webSocket实现扫码登录

    最近做了个新项目,涉及到扫码登录。之前项目使用的是 ajax轮询的方式。感觉太low了。所以这次用webSocket的方式进行实现,感兴趣的可以了解一下
    2021-06-06

最新评论