12.Stream Fork和Join原理
parallelStream()
使用的是Fork/Join 框架,Fork/Join框架自JDK7引入。
Fork/Join 框架可以将一个大任务拆分为很多小任务来异步执行。
Fork/Join 框架主要包含三个模块:
- 线程池:ForkJoinPool
- 任务对象:ForkJoinTask
- 执行任务的线程:ForkJoinWorkerThread
案例 Fork/Join案例
需求:
使用 Fork/Join 计算1-10000的和,当一个任务的计算数量大于3000的时候,拆分任务。 数量小于3000的时候就计算。
@Test
public void test1() {
long statr = System.currentTimeMillis();
ForkJoinPool pool = new ForkJoinPool();
SumRecursiveTask task = new SumRecursiveTask(1, 10000l);
Long result = pool.invoke(task);
System.out.println("result = " + result);
long times = System.currentTimeMillis() - statr;
System.out.println("times = " + times);
}
class SumRecursiveTask extends RecursiveTask<Long>{
// 定义一个拆分的临界值
private static final long THRESHOLD = 3000l;
private final long start;
public SumRecursiveTask(long start, long end) {
this.start = start;
this.end = end;
}
private final long end;
@Override
protected Long compute() {
// 写算法
long length = end - start;
if (length <=THRESHOLD){
// 任务不用拆分,可以计算
long sum = 0;
for (long i = start; i <= end; i++) {
sum += i;
}
System.out.println("计算 = " + start + "-->" + end +",的结果为:" + sum);
return sum;
}else{
// 数量大于预定的数量,那说明任务还需要继续拆分
long middle = (start + end) / 2;
System.out.println("拆分:左边" + start + "-->" + middle + ",右边" + (middle + 1)+"-->"+ end);
SumRecursiveTask leftTask = new SumRecursiveTask(start, middle);
SumRecursiveTask rightTask = new SumRecursiveTask(middle + 1, end);
// fork拆分
leftTask.fork();
rightTask.fork();
// join归并
return leftTask.join() + rightTask.join();
}
}
}
拆分:左边1-->5000,右边5001-->10000
拆分:左边1-->2500,右边2501-->5000
拆分:左边5001-->7500,右边7501-->10000
计算 = 1-->2500,的结果为:3126250
计算 = 5001-->7500,的结果为:15626250
计算 = 2501-->5000,的结果为:9376250
计算 = 7501-->10000,的结果为:21876250
result = 50005000
times = 3