java-11-Stream优化并行流

心已入冬 提交于 2019-12-04 03:53:34
 
并行流    多线程    把一个内容分成多个数据块  不同线程分别处理每个数据块的流
 
串行流   单线程  一个线程处理所有数据
 
java8 对并行流优化  StreamAPI 通过parallel()     并行流 
                                                        sequential()   顺序流  
 
注意:
使用并行流并不是一定会提高效率,因为jvm对数据进行切片和切换线程也是需要时间的。
所以数据量越小,串行操作越快;数据量越大,并行操作效果越好。
 
 
StreamAPI 通过parallel()     并行流   底层是Fork/join 框架
 
Fork/join 框架   将任务分解成  若干小任务(分解到不可分解为止)    小任务的结果 join汇总
 
Fork/Join与传统线程池的区别!
Fork/Join采用“工作窃取模式”,当执行新的任务时他可以将其拆分成更小的任务执行,并将小任务加到线程队列中,然后再从一个随即线程中偷一个并把它加入自己的队列中。
就比如两个CPU上有不同的任务,这时候A已经执行完,B还有任务等待执行,这时候A就会将B队尾的任务偷过来,加入自己的队列中,对于传统的线程,ForkJoin更有效的利用的CPU资源!
 
 
ForkJoin的实现:实现这个框架需要继承RecursiveTask 或者 RecursiveAction ,RecursiveTask是有返回值的,相反Action则没有
 
 1 package com.wf.zhang.java8.stream;
 2 
 3 import java.util.concurrent.RecursiveTask;
 4 
 5 
 6 public class ForkJoinCalculate extends RecursiveTask<Long> {
 7 
 8     private static final long serialVersionUID = 13475679780L;
 9     
10     private long start;
11     private long end;
12     
13     private static final long THRESHOLD = 10000L; //临界值
14 
15     //计算从start-end之和
16     public ForkJoinCalculate(long start, long end) {
17         this.start = start;
18         this.end = end;
19     }
20     
21     @Override
22     protected Long compute() {
23         long length = end - start;
24         
25         if(length <= THRESHOLD){
26             long sum = 0;
27             
28             for (long i = start; i <= end; i++) {
29                 sum += i;
30             }
31             return sum;
32         }else{
33             long middle = (start + end) / 2;
34             
35             ForkJoinCalculate left = new ForkJoinCalculate(start, middle);
36             left.fork(); //拆分,并将该子任务压入线程队列
37             
38             ForkJoinCalculate right = new ForkJoinCalculate(middle+1, end);
39             right.fork();
40             //汇总
41             return left.join() + right.join();
42         }
43         
44     }
45 
46 }
ForkJoinCalculate
 1 package com.wf.zhang.java8.stream;
 2 
 3 import org.junit.Test;
 4 
 5 import java.util.concurrent.ForkJoinPool;
 6 import java.util.concurrent.ForkJoinTask;
 7 import java.util.stream.LongStream;
 8 
 9 public class TestForkJoin {
10 
11     @Test
12     public void test1(){
13         long start = System.currentTimeMillis();
14 
15         ForkJoinPool pool = new ForkJoinPool();
16         ForkJoinTask<Long> task = new ForkJoinCalculate(0L, 10000000000L);
17 
18         long sum = pool.invoke(task);
19         System.out.println(sum);
20 
21         long end = System.currentTimeMillis();
22 
23         System.out.println("耗费的时间为: " + (end - start));
24     }
25 
26     //java8 优化并行流
27     @Test
28     public void test3(){
29         long start = System.currentTimeMillis();
30 
31         Long sum = LongStream.rangeClosed(0L, 10000000000L)
32                              .parallel()
33                              .sum();
34 
35         System.out.println(sum);
36 
37         long end = System.currentTimeMillis();
38 
39         System.out.println("耗费的时间为: " + (end - start));
40     }
41 }
TestForkJoin

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!