并行流 多线程 把一个内容分成多个数据块 不同线程分别处理每个数据块的流
串行流 单线程 一个线程处理所有数据
java8 对并行流优化 StreamAPI 通过parallel() 并行流
sequential() 顺序流
注意:
使用并行流并不是一定会提高效率,因为jvm对数据进行切片和切换线程也是需要时间的。
所以数据量越小,串行操作越快;数据量越大,并行操作效果越好。
StreamAPI 通过parallel() 并行流 底层是Fork/join 框架
Fork/join 框架 将任务分解成 若干小任务(分解到不可分解为止) 小任务的结果 join汇总
.png)
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 }

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 }
