在java7中新加入了ForkJoin,我是一个特别容易被新这个字吸引的人,好奇之下就去查了查资料,它是Java7提供的原生多线程并行处理框架,其基本思想是将一个大任务分割为一个个独立执行的子任务,再将子任务得到的结果聚合起来最终的result,在我看来,他的思想和快速排序算法有异曲同工之妙。ok,我们先看看我参照大神写的demo。
public class ForkJoin extends RecursiveTask<Integer> { public static final int threshold = 2; private int start; private int end; public ForkJoin(int start, int end){ this.start = start; this.end = end; } @Override protected Integer compute() { int sum = 0; boolean bool = (end - start)/2 <= threshold; if(bool){ for(int i = start; i<= end;i++){ sum += i; } } else { int center = (start+end)/2; ForkJoin one = new ForkJoin(start,center); ForkJoin two = new ForkJoin(center+1,end); one.fork();//执行子任务 two.fork(); int oneResult = one.join();//得到结果 int twoResult = two.join(); sum = oneResult+twoResult; } return sum; } public static void main(String[] args) throws ExecutionException, InterruptedException { ForkJoinPool pool = new ForkJoinPool(); ForkJoin forkJoin = new ForkJoin(1,100); Future<Integer> result = pool.submit(forkJoin); int i = result.get(); System.out.print(i); } }首先可以看到我们继承了RecursiveTask<T>类,我们需要注意的是:我们要使用ForkJoin框架,必须首先创建一个ForkJoin任务。它提供在任务中执行fork()和join的操作机制,通常我们不直接继承ForkjoinTask类,只需要直接继承其子类。 RecursiveAction:用于没有返回结果的任 务; RecursiveTask:用于有返回值的任务。这里我使用的是RecursiveTask<T>,这里的T是我们期望得到的结果的类型。我们还必须实现compute方法,定义我们具体的任务细节。
大家可以看到fork()是执行子任务:
public final ForkJoinTask<V> fork() { Thread t; if ((t = Thread.currentThread()) instanceof ForkJoinWorkerThread) ((ForkJoinWorkerThread)t).workQueue.push(this); else ForkJoinPool.common.externalPush(this); return this; }这个是fork方法的源码, 在当前任务正在运行的池中异步执行此任务(如果适用),或使用
ForkJoinPool.commonPool()
(
如果不是
inForkJoinPool()
)进行异步执行
。这个是java api的解释,很明显是把我们的任务加入到了工作队列中去。fork方法是得到我们任务的结果,然后将结果聚合一下就定义好了我们的任务,就是一个累加。
接下来再来看main方法里面的代码,ForkJoinPool是什么呢?查看源码可以发现public class ForkJoinPool extends AbstractExecutorService,是不是立马就感觉原来如此,对的,ForkJoinPool就是专为forkjoin框架定制的线程池,具体的实现细节咱们可以先不看,一看到submit是不是感觉很熟悉,没错我也是这样,看到这个方法我就想起了callable接口,事实上的确如同我们猜测的那样,这两个方法的作用是类似的,都是执行任务并得到返回结果。
得到的结果如图所示:
5050
Process finished with exit code 0
像这种求和以及排序的需求都可以通过FORKJOIN思想来实现,希望对大家有所帮助。