第06篇 并行流和fork-join框架

本文详细介绍了Java8中的并行流和fork-join框架,通过实例展示了如何利用并行流提高计算效率,分析了并行流在求和计算中的优化过程,包括避免拆装箱。此外,还探讨了fork-join框架的工作原理、使用建议以及Spliterator在并行计算中的作用。
摘要由CSDN通过智能技术生成

为了让我们的程序运行的更加高效,CPU的使用效率更高,我们可以通过让程序并行执行的方式让所有的CPU都忙碌起来,从而提供程序执行的效率。

有两种方式来实现并行:java8的fork-join框架、java8中的并行流(底层依然是fork-join框架)。
这里我们以计算n以内数字的和为例进行改进,也让我们能够很好的看到效果。

首先,我们定义要求和的最大数为:Long max = 1000000000L;

一、并行流

(一)经典for循环

首先我们使用经典的for循环,串行进行遍历求和:

 @Test
 public void serial() {
     long sum = 0;
     long start = System.currentTimeMillis();
     for (long i = 0; i <= max; i++) {
         sum += i;
     }
     long end = System.currentTimeMillis();
     System.out.println(String.format("for循环串行计算,sum:%d,总共耗时为:%d", sum, (end - start)));
 }

效果如下:

for循环串行计算,sum:500000000500000000,总共耗时为:363

(二)Stream求和

接下来,我们使用stream来遍历求和,代码如下:

@Test
public void java8Stream() {
    long start = System.currentTimeMillis();
    Long sum = Stream.iterate(1L, i -> i + 1)
            .limit(max)
            .reduce(0L, Long::sum);
    long end = System.currentTimeMillis();
    System.out.println(String.format("java8流式计算,sum:%d,总共耗时为:%d", sum, (end - start)));
}

效果如下:
java8流式计算,sum:500000000500000000,总共耗时为:11660

我们会发现,这种方式比for循环慢了很多,产生的原因主要如下:

  1. Stream本身也是串行的;
  2. 在进行计算的时候,我们使用的Stream流会使用包装类,在计算的时候要进行拆箱和装箱过程,会消耗大量的时间。

(三)Stream并行求和

我们可以通过把流转换成并行流来进行计算

 @Test
 public void java8Parallel() {
     long start = System.currentTimeMillis();
     long sum = Stream.iterate(1L, i -> i + 1)
             .limit(max)
             .parallel() //获取并行流
             .reduce(0L, Long::sum);
     long end = System.currentTimeMillis();
     System.out.println(String.format("Java8并行流计算,sum:%d,总共耗时为:%d", sum, (end - start)));
 }

效果:
在这里插入图片描述
可以看到,直接发生了内存溢出,产生原因如下:

  1. 和上面一样,包装类会对相率产生极大的影响;
  2. fork-join框架底层需要使用Spliterator(后续讲解)对迭代器进行切割,进一步出现了问题;

(四)去掉拆装箱的Stream并行

在使用的时候,我们应当尽量避免包装类的转换,所以,我们可以使用LongStream 来获取数据,这样的话,就避免了不必要的拆箱和装箱。其他的场景下,我们也需要注意这一点。

@Test
public void java8ParallelWtihoutPackage() {
    long start = System.currentTimeMillis();
    long sum = LongStream.rangeClosed(0, max)
            .parallel() //获取并行流
            .sum();
    long end = System.currentTimeMillis();
    System.out.println(String.format("Java8并行流计算,去掉装箱拆箱,sum:%d,总共耗时为:%d", sum, (end - start)));
}

效果如下:
Java8并行流计算,去掉装箱拆箱,sum:500000000500000000,总共耗时为:252

并行流的获取

上面演示了串行到并行流的演

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值