您的位置:首页 > 编程语言 > Java开发

java多线程之并行框架ForkJoin

2017-07-23 22:47 399 查看
在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;
}

aff7
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思想来实现,希望对大家有所帮助。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: