分支合并框架ForkJoinPool
原理说明:就是在必要情况下,将一个大任务,进行拆分(fork)成若干个小任务(拆到不可再拆时),再将一个个的小任务运算的结果进行join汇总
![file](https://i-blog.csdnimg.cn/blog_migrate/eb40035e75ba00b8a1dca6933acd083f.png)
示例:示例是一个1亿的累加,100亿的累加,500亿的累加。采用三种算法,一种是ForkJoinPool框架,一种是jdk1.8的算法框架,一种是传统的循环相加的算法
依次给出了运算的时间:
示例代码:
package com.debuggg.test1.main2;
import org.junit.jupiter.api.Test;
import java.time.Duration;
import java.time.Instant;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
import java.util.stream.LongStream;
public class TestForkJoinPool {
public static void main(String[] args) {
Instant start = Instant.now();
ForkJoinSum forkJoinSum = new ForkJoinSum(0L, 50000000000L);
ForkJoinPool pool = new ForkJoinPool();
Long sum = pool.invoke(forkJoinSum);
System.out.println(sum);
Instant end = Instant.now();
System.out.println("耗费时长为:" + Duration.between(start,end).toMillis());//1亿是83ms,100亿是3152,5百亿是13869
}
@Test
public void test1(){
Instant start = Instant.now();
long sum = 0;
for (long i = 0; i < 50000000000L; i++) {
sum += i;
}
System.out.println(sum);
Instant end = Instant.now();
System.out.println("耗费时长为: " + Duration.between(start,end).toMillis());//1亿是46ms,100亿是5167,5百亿是24323
}
@Test
public void test2(){
Instant start = Instant.now();
long sum = LongStream.rangeClosed(0L, 10000000000L).parallel().reduce(0L, (a, b) -> Long.sum(a, b));
System.out.println(sum);
Instant end = Instant.now();
System.out.println("耗费时长为:" + Duration.between(start,end).toMillis());//1亿是217,1百亿是1956,5百亿是9923
}
}
class ForkJoinSum extends RecursiveTask<Long> {
private static final long serialVersionUID = -1;
private long start;
private long end;
private static final long THRESHOLD = 10000L;
public ForkJoinSum(long start, long end){
this.start = start;
this.end = end;
}
@Override
protected Long compute() {
if(end - start <= THRESHOLD){
long sum = 0L;
for (long i = start; i <= end; i ++){
sum += i;
}
return sum;
}else{
long middle = (start + end) / 2;
ForkJoinSum left = new ForkJoinSum(start, middle);
left.fork();
ForkJoinSum right = new ForkJoinSum(middle + 1, end);
right.fork();
return left.join() + right.join();
}
}
}