为什么要在invokeAll方法之后调用join? [英] Why should we call join after invokeAll method?

查看:133
本文介绍了为什么要在invokeAll方法之后调用join?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试了解ForkJoinPool框架,并遇到以下示例:

I am trying to learn about the ForkJoinPool framework and came across the below example:

 public class ArrayCounter extends RecursiveTask<Integer> {
 int[] array;
 int threshold = 100_000;
 int start;
 int end;

 public ArrayCounter(int[] array, int start, int end) {
    this.array = array;
    this.start = start;
    this.end = end;
  }

  protected Integer compute() {
    if (end - start < threshold) {
        return computeDirectly();
    } else {
        int middle = (end + start) / 2;

        ArrayCounter subTask1 = new ArrayCounter(array, start, middle);
        ArrayCounter subTask2 = new ArrayCounter(array, middle, end);

        invokeAll(subTask1, subTask2);


        return subTask1.join() + subTask2.join();
    }
 }

 protected Integer computeDirectly() {
    Integer count = 0;

    for (int i = start; i < end; i++) {
        if (array[i] % 2 == 0) {
            count++;
        }
    }

    return count;
}
}

主要:

  public class ForkJoinRecursiveTaskTest
  {
  static final int SIZE = 10_000_000; 
  static int[] array = randomArray();
  public static void main(String[] args) {
  ArrayCounter mainTask = new ArrayCounter(array, 0, SIZE);
  ForkJoinPool pool = new ForkJoinPool();
  Integer evenNumberCount = pool.invoke(mainTask);
  System.out.println("Number of even numbers: " + evenNumberCount);
  }
  static int[] randomArray() {
  int[] array = new int[SIZE];
  Random random = new Random();
  for (int i = 0; i < SIZE; i++) {
  array[i] = random.nextInt(100);
  }
  return array;
  }
  }

根据Java Docs,invokeAll()将任务提交到池中并返回结果.因此,不需要单独的join().有人可以解释为什么在这种情况下为什么需要单独的联接吗?

According to the Java Docs,invokeAll() submits the tasks to the pool and returns the results as well.Hence no need for a separate join(). can someone please explain why a separate join is needed in this case?

推荐答案

在您的示例中,您使用的是RecursiveTask<Integer> 因此,您期望从compute()方法返回一个值.

in your example, you are using RecursiveTask<Integer> so you are expecting to return a value from compute() method.

让我们看看invokAll(t1,t12)签名.

static void invokeAll(ForkJoinTask<?> t1, ForkJoinTask<?> t2)

所以invokeAll()没有返回值. 根据文档:

so invokeAll() doesn't have return a value. according to the documentation :

分叉给定的任务,返回isDone保留每个任务的时间或遇到(未检查的)异常,在这种情况下,该异常将被重新抛出.

Forks the given tasks, returning when isDone holds for each task or an (unchecked) exception is encountered, in which case the exception is rethrown.

所以:

return subTask1.join() + subTask2.join();是您的示例的键. 每次完成任务后,这两个任务将合并,然后将结果递归传递给下一个compute()方法调用.

return subTask1.join() + subTask2.join(); is the key for your example. both tasks are merged after each complete the task passing the result recursivly to the next call of compute() method.

task.join()

完成后返回计算结果.

Returns the result of the computation when it is done.

这篇关于为什么要在invokeAll方法之后调用join?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆