fork-join说白了就是分治的方法,不断递归,明白二分法的话就很容易理解,但要注意的是,由于fork-join涉及到切换线程上下文,因此不是所有情况下都是能加快速度的。举例,测试一个大数组的求和,可以不断用分段的方法,求出每个范围(比如把数组分成10个部分,每个部分分别求和)。
public class SumArray {
private static class SumTask extends RecursiveTask<Integer>{
private final static int THRESHOLD = MakeArray.ARRAY_LENGTH/10;
//表示我们要实际统计的数组
private int[] src;
//开始统计的下标
private int fromIndex;
//统计到哪里结束的下标
private int toIndex;
public SumTask(int[] src, int fromIndex, int toIndex) {
this.src = src;
this.fromIndex = fromIndex;
this.toIndex = toIndex;
}
@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);
invokeAll(left,right);
return left.join()+right.join();
}
}
}
public static void main(String[] args) {
ForkJoinPool pool = new ForkJoinPool();
//随机生成数组
int[] src = MakeArray.makeArray();
SumTask innerFind = new SumTask(src,0,src.length-1);
long start = System.currentTimeMillis();
pool.invoke(innerFind);//同步调用
System.out.println("Task is Running.....");
System.out.println("The count is "+innerFind.join()
+" spend time:"+(System.currentTimeMillis()-start)+"ms");
}
}
在上面的例子中,针对随机数组,一开始指出头部和尾部下标,然后不断进行递归操作就可以了,上面是个标准的
fork-join的模板了