Fork-Join框架的简单使用

一、Fork-Join框架作用

 Fork/Join框架是Java 7提供的一个用于并行执行任务的框架,是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架。Fork/Join框架要完成两件事情:

  1.任务分割:首先Fork/Join框架需要把大的任务分割成足够小的子任务,如果子任务比较大的话还要对子任务进行继续分割

  2.执行任务并合并结果:分割的子任务分别放到双端队列里,然后几个启动线程分别从双端队列里获取任务执行。子任务执行完的结果都放在另外一个队列里,启动一个线程从队列里取数据,然后合并这些数据。

  在Java的Fork/Join框架中,使用两个类完成上述操作

  1.ForkJoinTask:我们要使用Fork/Join框架,首先需要创建一个ForkJoin任务。该类提供了在任务中执行fork和join的机制。通常情况下我们不需要直接集成ForkJoinTask类,只需要继承它的子类,Fork/Join框架提供了两个子类:
a.RecursiveAction:用于没有返回结果的任务
b.RecursiveTask:用于有返回结果的任务

  2.ForkJoinPool:ForkJoinTask需要通过ForkJoinPool来执行

  任务分割出的子任务会添加到当前工作线程所维护的双端队列中,进入队列的头部。当一个工作线程的队列里暂时没有任务时,它会随机从其他工作线程的队列的尾部获取一个任务(工作窃取算法)。

二、Fork-Join框架举例

package com.roocon.thread.tc1;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.Future;
import java.util.concurrent.RecursiveTask;

/**
 * ForkJoin框架的简单尝试(计算begin....end的累加和,比如1+2+3...+100)
 * @author superman
 *
 */
public class ForkJoin  extends RecursiveTask<Integer>{


    private static final long serialVersionUID = 28980553733573142L;

    private int begin;  //计算累加和的起点
     private int end;    //计算累加和的终点


    public ForkJoin(int begin, int end) {
        super();
        this.begin = begin;
        this.end = end;
    }

    @Override
    protected Integer compute() {
        System.out.println(Thread.currentThread().getName()+"线程开始执行");

        int sum=0;

        //任务拆分
        if(end-begin<=1) {
            //计算小和
            for(int i=begin;i<=end;i++)
                sum+=i;
        }else {
              //拆分
             ForkJoin d1= new ForkJoin(begin,(begin+end)/2);
             ForkJoin d2= new ForkJoin((begin+end)/2+1,end);

             //拆分执行任务
             d1.fork();
             d2.fork();

             Integer a=d1.join();
             Integer b=d2.join();
             sum=a+b;
        }

        return sum;
    }

    //单线程执行结果
    public static int getadd(int begin,int end) {
        int sum=0;
        for(int i=begin;i!=end+1;i++) {
            sum+=i;
        }
        return sum;
    }
    public static void main(String[] args) throws Exception {
        //多线程分而治之
        long start=System.currentTimeMillis();
        ForkJoinPool pool=new ForkJoinPool();
        Futurefuture=pool.submit(new ForkJoin(1,1000000));
        long end=System.currentTimeMillis();
        System.out.println("----------------------");
        System.out.println("计算的结果为:"+future.get()+"计算的时间为"+(end-start));


        //单线程执行
        long start1=System.currentTimeMillis();
        int sum=getadd(1,1000000);
        long end1=System.currentTimeMillis();
        System.out.println("计算的结果为:"+sum+"计算的时间为"+(end1-start1));

    }

}

Fork-Join框架的简单使用_第1张图片

你可能感兴趣的:(java多线程,常见面试题,Java学习专栏)