前言

时间有限, 就先写着,有时间补注释

概念问题在这里:​

准备数据源工具类

使用根据类准备

import java.util.Random;

/**
* 准备数组工具类
*/
public class MakeArrayUtil {
//数组长度 如果设置过大,会使得计算结果变为负数
public static final int ARRAY_LENGTH = 10000;
public final static int THRESHOLD = 47;

public static int[] makeArray() {

//new一个随机数发生器
Random r = new Random();
int[] result = new int[ARRAY_LENGTH];
for (int i = 0; i < ARRAY_LENGTH; i++) {
//用随机数填充数组
result[i] = r.nextInt(ARRAY_LENGTH * 3);
}
return result;

}
}

不使用ForkJoin单线程累计工作

public class Main {
public static void main(String[] args) {
int count = 0;
int[] src = MakeArrayUtil.makeArray();

long start = System.currentTimeMillis();
for (int i = 0; i < src.length; i++) {
SleepTools.ms(1);
count = count + src[i];
}
System.out.println("总数是 " + count
+ " 耗时" + (System.currentTimeMillis() - start) + "ms");
}
}

控制台打印结果: 总数是 150190419 耗时18051ms

花费了18051ms

使用ForkJoin累计工作

这个MakeArrayUtil数据源和上面的不使用ForkJoin单线程累计工作的类是一个类.所以是一个数据源

import utils.SleepTools;

import java.util.concurrent.RecursiveTask;

public class SumTask extends RecursiveTask<Integer> {

/*阈值(拆分到多小的时候不拆分了,直接进行计算) 数组长度除以10*/
private final static int THRESHOLD = MakeArrayUtil.ARRAY_LENGTH / 10;
private int[] src; //原始数组
private int fromIndex;
private int toIndex;

/**
* 构造
* @param src 数组
* @param fromIndex 数组的起始索引
* @param toIndex 数组的最大索引
*/
public SumTask(int[] src, int fromIndex, int toIndex) {
this.src = src;
this.fromIndex = fromIndex;
this.toIndex = toIndex;
}

/**
* 执行计算的方法
* @return
*/
@Override
protected Integer compute() {
/*任务的大小是否合适
结束索引-起始索引小于阈值了就直接汇总统计
* */
if (toIndex - fromIndex < THRESHOLD) {
int count = 0;
for (int i = fromIndex; i <= toIndex; i++) {
SleepTools.ms(1);
count = count + src[i];
}
return count; // 结果返回出去
} else {// 大于阈值 就对半拆分


//fromIndex....mid.....toIndex
int mid = (fromIndex + toIndex) / 2; //求中间值

//拆分成两个
SumTask left = new SumTask(src, fromIndex, mid);//左半边
SumTask right = new SumTask(src, mid + 1, toIndex);//右半边(注意一定要中间值索引加1)
invokeAll(left, right);//把左右子任务拿到池子里面去执行
return left.join() + right.join(); //拿到两个子任务的值(左边加右边)
}
}
}
public class Main {
/**
* 统计数组的所有的元素的和案例
* 用 ForkJoin
*/
public static void main(String[] args) {

int[] src = MakeArrayUtil.makeArray();
/*new出池的实例*/
ForkJoinPool pool = new ForkJoinPool();
/*new出Task的实例*/
SumTask innerFind = new SumTask(src, 0, src.length - 1);


long start = System.currentTimeMillis();
//开始执行
Integer invoke = pool.invoke(innerFind); //同步执行 获取结果,会在计算之后打印下面的话
// ForkJoinTask<Integer> submit = pool.submit(innerFind); //异步执行,会在计算完成之前打印下面的话
System.out.println("执行完成了");

//System.out.println("Task is Running.....");
Integer count = innerFind.join();

System.out.println("总数是 " + count
+ " 耗时" + (System.currentTimeMillis() - start) + "ms");

}
}

控制台打印:
执行完成了
总数是 150759206 耗时2273ms

总结

不使用ForkJoin的情况下耗时18051ms , 使用ForkJoin的情况下耗时2273ms