ForkJoinPool

ForkJoinPool是ExecutorService的实现类,也是一种特殊的线程池。它提供了如下两个常用的构造器:

  • ForkJoinPool(int parallelism):创建一个包含parallelism个并行线程的ForkJoinPool。
  • ForkJoinPool():以Runtime.availableProcessors()方法的返回值作为parallelism参数来创建ForkJoinPool。

在java8进一步丰富了ForkJoinPool的功能,为其增加了通用池功能。通过如下两个静态方法提供通用池的功能:

  • ForkJoinPool commonPool():该方法返回一个通用池,通用池的运行状态不会受shutdown()或shutdownNow()方法的影响。
  • int getCommonPoolParallelism():该方法返回通用池的并行级别。

创建ForkJoinPool后就可以调用submit(ForkJoinTask task) 或 invoke(ForkJoinTask task)方法来执行指定任务了。其中ForkJoinTask代表一个可以并行、合并的任务。

ForkJoinTask是一个抽象类,它还有两个抽象子类:RecursiveAction和RecursiveTask。

其中RecursiveAction代表没有返回值的任务,例如:

public class PrintTask extends RecursiveAction {

  //每个"小任务"最多打印50次
  private static final int THRESHOLD = 50;

  private int start;

  private int end;

  public PrintTask(int start, int end) {
    this.start = start;
    this.end = end;
  }

  @Override
  protected void compute() {

    //当end与start之间的差值小于THRESHOLD时开始打印
    if (end - start < THRESHOLD){
      for(int i = start; i < end; i++) {
        System.out.println(Thread.currentThread().getName() + " 的i值:" + i);
      }
    } else {
      //当end与start之间当差值大于THRESHOLD时进行任务拆解
      int middle = (start + end) >> 1;
      PrintTask left = new PrintTask(start, middle);
      PrintTask right = new PrintTask(middle, end);
      //并行执行两个"小任务"
      left.fork();
      right.fork();
    }

  }

  public static void main(String[] args) throws Exception{

    ForkJoinPool pool = new ForkJoinPool();
    //提交可分解当PrintTask任务
    pool.submit(new PrintTask(0,400));
    pool.awaitTermination(2, TimeUnit.SECONDS);
    //关闭线程池
    pool.shutdown();

  }

}

RecursiveTask代表有返回值的任务,例如:

public class CalTask extends RecursiveTask<Integer> {

  //每个"小任务"最多累加50次
  private static final int THRESHOLD = 50;

  private int arr[];

  private int start;

  private int end;

  public CalTask(int[] arr, int start, int end) {
    this.arr = arr;
    this.start = start;
    this.end = end;
  }

  @Override
  protected Integer compute() {

    int sum = 0;

    //当end与start之间的差值小于THRESHOLD时开始累加计算
    if (end - start < THRESHOLD){
      for (int i = start; i < end; i++){
        sum += arr[i];
      }
      return sum;
    } else {
      int middle = (start + end) >> 1;
      CalTask left = new CalTask(arr, start,middle);
      CalTask right = new CalTask(arr, middle, end);
      left.fork();
      right.fork();
      return left.join()+right.join();
    }


  }

  public static void main(String[] args) throws Exception{
    int[] arr = new int[200];
    Random random = new Random();
    int total = 0;
    //初始化数组
    for (int i = 0; i < arr.length; i++){
      int tmp = random.nextInt(20);
      total += (arr[i] = tmp);
    }

    System.out.println("total = " + total);

    //创建一个通用池
    ForkJoinPool pool = ForkJoinPool.commonPool();

    //提交可分解的Caltask任务
    Future<Integer> future = pool.submit(new CalTask(arr, 0, arr.length));
    System.out.println(future.get());

    //关闭线程池
    pool.shutdown();

  }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值