java多线程之并行框架ForkJoin

在java7中新加入了ForkJoin,我是一个特别容易被新这个字吸引的人,好奇之下就去查了查资料,它是Java7提供的原生多线程并行处理框架,其基本思想是将一个大任务分割为一个个独立执行的子任务,再将子任务得到的结果聚合起来最终的result,在我看来,他的思想和快速排序算法有异曲同工之妙。ok,我们先看看我参照大神写的demo。

public class ForkJoin extends RecursiveTask {
    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 result = pool.submit(forkJoin);
        int i = result.get();
        System.out.print(i);
    }
}
首先可以看到我们继承了RecursiveTask类,我们需要注意的是:我们要使用ForkJoin框架,必须首先创建一个ForkJoin任务。它提供在任务中执行fork()和join的操作机制,通常我们不直接继承ForkjoinTask类,只需要直接继承其子类。  RecursiveAction:用于没有返回结果的任   务;  RecursiveTask:用于有返回值的任务。这里我使用的是RecursiveTask,这里的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思想来实现,希望对大家有所帮助。

你可能感兴趣的:(Java多线程,java,并行处理,ForkJoin,java,7,多线程)