描述
任务量大,数据量大,使用多线程forkjoin,加快速度,提高效率,比如一百万个数求和
forkjoin可分为两个部分,fork 把发任务分成小任务,一个子线程负责一个小任务, join合并线程执行结果,整个过程使用递归实现,如图所示
代码实现
public interface Calculator {
long sumUp(long[] numbers);
}
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
/**
* @program: arask
* @description: forkjoin
* @author: fubowen
* @create: 2020-06-28 14:41
**/
public class ForkJoinCalculator implements Calculator {
private ForkJoinPool pool;
ForkJoinCalculator(){
pool=new ForkJoinPool();
}
//求和方法
@Override
public long sumUp(long[] numbers) {
//forkjoin调用
long sum=pool.invoke(new SumTask1(numbers,0,numbers.length-1));
pool.shutdown();
return sum;
}
}
class SumTask1 extends RecursiveTask<Long>{
private long[] numbers;
private int from;
private int to;
SumTask1(long[] numbers,int from,int to){
this.numbers=numbers;
this.from=from;
this.to=to;
}
@Override
protected Long compute() {
long sum=0;
if(to-from<1000){
for (int i = from; i <=to ; i++) {
sum+=numbers[i];
}
return sum;
}else {
//递归分任务
int middle=(from+to)/2;
SumTask1 sumTask1=new SumTask1(numbers,from,middle);
SumTask1 sumTask2=new SumTask1(numbers,middle+1,to);
sumTask1.fork();
sumTask2.fork();
//join合并结果
sum=sumTask1.join()+sumTask2.join();
return sum;
}
}
}
测试
/**
* @program: arask
* @description: 求和测试类
* @author: fubowen
* @create: 2020-06-28 10:41
**/
public class CalculatorTest {
public static void main(String[] args) {
long length=100000000L;
Calculator calculator=new ForkJoinCalculator();
long[] numbers= LongStream.rangeClosed(1,length).toArray();
long startTime=System.currentTimeMillis();
long sum=calculator.sumUp(numbers);
long endTime=System.currentTimeMillis();
System.out.println("耗时:"+(endTime-startTime)+"ms");
System.out.println("结果:"+sum);
}
}