学习lambda03-lambda和forkjoin
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.LongStream;
/**
继 承 Recur-
siveTask 来
创 建 可 以 用
于分支/合并
框架的任务
**/
public class ForkJoinSumCalculator extends RecursiveTask<Long>
{
/**
* 不再将任务分
* 解为子任务的
* 数组大小 (也就是用于递归出来的条件,当小于10000的时候就会计算(单个子任务)求和结果)
*/
public static final long THRESHOLD = 3;
public static final ForkJoinPool FORK_JOIN_POOL = new ForkJoinPool();
private final long[] numbers; //需要求和的数组
private final int start; //开始
private final int end;//结束
/**
* 公共构造
* 函数用于
* 创建主任
* 务
* @param numbers
*/
public ForkJoinSumCalculator(long[] numbers) {
this(numbers, 0, numbers.length);
}
/**
* 私有构造函数用于以递
* 归方式为主任务创建子
* 任务
* @param numbers
* @param start
* @param end
*/
private ForkJoinSumCalculator(long[] numbers, int start, int end) {
this.numbers = numbers;
this.start = start;
this.end = end;
}
private static AtomicInteger integer = new AtomicInteger(0);
@Override
protected Long compute() {
integer.getAndAdd(1);
int length = end - start;
if (length <= THRESHOLD) {
return computeSequentially();
}
/**
* 创建一个子任
* 务来为数组的
* 前一半求和
* 假设numbers = 10 , 那么 new ForkJoinSumCalculator(10, 0,5);
*/
ForkJoinSumCalculator leftTask = new ForkJoinSumCalculator(numbers, start, start + length/2);
/**
* 利 用 另 一 个
* ForkJoinPool
* 线程异步执行新
* 创建的子任务
* 假设numbers = 10 , 那么 new ForkJoinSumCalculator(10, 5,10);
*/
leftTask.fork();
ForkJoinSumCalculator rightTask = new ForkJoinSumCalculator(numbers, start + length/2, end);
/**
* 同步(注意是同步,也就是会有阻塞)执行第二个子
* 任务,有可能允许进
* 一步递归划分
*/
Long rightResult = rightTask.compute();
/**
* 读取第一个子任务的结果,
* 如果尚未完成就等待
*/
Long leftResult = leftTask.join();
/**
* 对两个子任务的结果求和
*/
return leftResult + rightResult;
}
private long computeSequentially() {
long sum = 0;
for (int i = start; i < end; i++) {
sum += numbers[i];
}
return sum;
}
public static long forkJoinSum(long n) {
long[] numbers = LongStream.rangeClosed(1, n).toArray();
ForkJoinTask<Long> task = new ForkJoinSumCalculator(numbers);
return FORK_JOIN_POOL.invoke(task);
}
public static void main(String[] args) {
long l = forkJoinSum(10);
System.out.println(integer); //打印计数器为7 ,通过断点查看确实是进入了7次
System.out.println(l);
}
}
程序执行大概流程