ForkJoin是一种策略:在必要的情况下,将一个大的任务,根据阈值进行拆分(Fork)成若干个小任务,再将一个个的小任务的解进行join汇总;
示例代码:
/**
* 任务:使用ForkJoin的方式将一个数组中的值进行累加
*/
public class ForkJoinDemo extends RecursiveTask<Integer> {
//数组的长度
private static int arrayLength = 100000;
//数组
private int[] array;
//开始下标
private int begin;
//结束下标
private int end;
private ForkJoinDemo(int[] array, int begin, int end) {
this.array = array;
this.begin = begin;
this.end = end;
}
/**
* (ARRAY_LENGTH / 10)的结果就是在本demo中所谓的阈值
* 1、首先判断数组长度是否小于阈值,若小于,将结果进行累加返回;
* 2、若不符合条件,则进行拆分,并调用invokeAll()方法进行派生任务,
* 最后讲每个小任务的结果相加返回
*/
@Override
protected Integer compute() {
//
//
if (end - begin < (arrayLength / 10)) {
int count = 0;
for (int i = begin; i <= end; i++) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
count += array[i];
}
return count;
} else {
int mid = (begin + end) / 2;
ForkJoinDemo left = new ForkJoinDemo(array, begin, mid);
ForkJoinDemo right = new ForkJoinDemo(array, mid + 1, end);
invokeAll(left, right);
return left.join() + right.join();
}
}
/**
* 生成一个数组,长度为arrayLength,数组内的值随机生成,大小在arrayLength * 3以内;
*/
private static int[] generateArray() {
Random random = new Random();
int arr[] = new int[arrayLength];
for (int i = 0; i < arrayLength; i++) {
arr[i] = random.nextInt(arrayLength * 3);
}
return arr;
}
public static void main(String[] args) {
ForkJoinPool pool = new ForkJoinPool();
//调用方法,生成一个数组
int[] ints = generateArray();
long begin = System.currentTimeMillis();
ForkJoinDemo forkDemo = new ForkJoinDemo(ints, 0, arrayLength - 1);
//调用ForkJoin的同步方法
pool.invoke(forkDemo);
System.out.println("结果:" + forkDemo.join());
System.out.println("耗时:" + (System.currentTimeMillis() - begin));
}
}