1.步骤代码:
1.代码类ForkJoinCalculate
import java.util.concurrent.RecursiveTask;
/**
* 创建日期:2021/11/9 14:10
*
* @author tony.sun
* 类说明:
*/
public class ForkJoinCalculate extends RecursiveTask<Long> {
public static final long serialVersionUID=1234345435L;//序列号版本号
private long start;
private long end;
public ForkJoinCalculate(long start, long end) {
this.start = start;
this.end = end;
}
public static final long THRESHOLD=10000;//数值太小的话,没必要用并行流,这样更加耗费时间,其实这里值是太小的
@Override
protected Long compute() {
long length=end-start;
//下面的作用,数值太少的话,反而更加耗费时间(拆分要时间)
if (length<=THRESHOLD) {
long sum=0;
for (long i = start; i <=end ; i++) {
sum+=i;
}
return sum;
}else {
long middle=(start+end)/2;//中间拆分
//拆分的左边
ForkJoinCalculate forkJoinCalculateLeft = new ForkJoinCalculate(start, middle);
forkJoinCalculateLeft.fork();//拆分子任务,同时压入线程队列
//拆分的右边
ForkJoinCalculate forkJoinCalculateRight = new ForkJoinCalculate(start, middle);
forkJoinCalculateRight.fork();//拆分子任务,同时压入线程队列
//返回合并
return forkJoinCalculateLeft.join()+forkJoinCalculateRight.join();
}
}
}
1.构造方法
public ForkJoinCalculate(long start, long end) {
this.start = start;
this.end = end;
}
这个是传如要计算的值,从哪里累加到哪里,如输入0,和10000,就是1+2+……10000;
2.THRESHOLD表示最小的累加最大最小的差值,
如输入0,和10000,那么他们的差就是10000。为什么要这个值呢,因为并行流对于太小的值,发挥不了高效的效果,值太小,反而更慢。
3.middle表示对累加的值进行中间拆分,来运算,再合并,如下图。我们这里进行的是(0+10000)/2
2.测试类
测试类有三种;我们编写的并行类,for,还有最后的Java提供的方法,时间有注释
import java.time.Duration;
import java.time.Instant;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.stream.LongStream;
/**
* 创建日期:2021/11/9 14:41
*
* @author tony.sun
* 类说明:
*/
public class TestForkJoin {
@Test
public void test1(){
//获取运行前时间
Instant start = Instant.now();
//并行流池
ForkJoinPool pool = new ForkJoinPool();
ForkJoinTask<Long> task=new ForkJoinCalculate(0,10000000000L);
Long sum = pool.invoke(task);
System.out.println(sum);
Instant end = Instant.now();
System.out.println("耗费时间为:"+ Duration.between(start,end).toMillis());//1亿是39,100亿是808
}
/**
* 普通for
*/
@Test
public void test2(){
Instant start = Instant.now();
long sum=0L;
for (long i = 0; i < 10000000000L; i++) {
sum+=i;
}
System.out.println(sum);
Instant end = Instant.now();
System.out.println("耗费时间为:"+ Duration.between(start,end).toMillis());//1亿是27,100亿是2400
}
/**
* java8
*/
@Test
public void test3(){
Instant start = Instant.now();
LongStream.rangeClosed(0,10000000000L)
.parallel()
.reduce(0,Long::sum);
Instant end = Instant.now();
System.out.println("耗费时间为:"+ Duration.between(start,end).toMillis());//100亿是651
}
}
2.注意
依赖要添加为Java1.8
java {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}