并行编程。compute()方法,java

并行编程。compute()方法,java,java,data-structures,mergesort,Java,Data Structures,Mergesort,我有一个扩展了递归动作的类。 同一个类包含以数组为参数的构造函数和compute()方法。 在compute方法中,它表示下一步: 如果array长度大于500,则将该数组分成两半,并使用MergeSort.merge()方法对其进行排序。如果数组长度小于500,只需对数组进行排序 private static class SortTask extends RecursiveAction { private final int THRESHOLD = 500; private i

我有一个扩展了递归动作的类。 同一个类包含以数组为参数的构造函数和
compute()
方法。 在compute方法中,它表示下一步: 如果
array
长度大于500,则将该数组分成两半,并使用
MergeSort.merge()方法对其进行排序。如果数组长度小于500,只需对
数组进行排序

private static class SortTask extends RecursiveAction {
   private final int THRESHOLD = 500;
     private int[] list;
      SortTask(int[] list) {
       this.list = list;
         }
        @Override
protected void compute() {
if (list.length < THRESHOLD)
java.util.Arrays.sort(list);
else {
    // Obtain the first half
int[] firstHalf = new int[list.length / 2];
System.arraycopy(list, 0, firstHalf, 0, list.length / 2);


// Obtain the second half
int secondHalfLength = list.length - list.length / 2;
int[] secondHalf = new int[secondHalfLength];
System.arraycopy(list, list.length / 2,
secondHalf, 0, secondHalfLength);
// Recursively sort the two halves
invokeAll(new SortTask(firstHalf),
new SortTask(secondHalf));
// Merge firstHalf with secondHalf into list
MergeSort.merge(firstHalf, secondHalf, list);
}
}
}
}

这是否意味着每次创建
new
SortTask
对象时,都会调用
compute()
方法

答案是否定的。Compute不是
任务的一部分。最简单的情况是pool
shutdownNow()
-此调用将尝试终止/中断所有提交的任务

每次
new SortTask
创建
ForkJoinPool
分叉此任务时:

public static void invokeAll(ForkJoinTask<?>... tasks) {
    Throwable ex = null;
    int last = tasks.length - 1;
    for (int i = last; i >= 0; --i) {
        ForkJoinTask<?> t = tasks[i];
        if (t == null) {
            if (ex == null)
                ex = new NullPointerException();
        }
        else if (i != 0)
            t.fork();
    ...
}
ForkJoinWorkerThread
具有以下方法:

final void More execTask(ForkJoinTask<?> t) {
    currentSteal = t;
    for (;;) {
       if (t != null)
           t.doExec();
    ...
}

答案是否定的。Compute不是
任务
构造函数的一部分。最简单的情况是pool
shutdownNow()
-此调用将尝试终止/中断所有提交的任务

每次
new SortTask
创建
ForkJoinPool
分叉此任务时:

public static void invokeAll(ForkJoinTask<?>... tasks) {
    Throwable ex = null;
    int last = tasks.length - 1;
    for (int i = last; i >= 0; --i) {
        ForkJoinTask<?> t = tasks[i];
        if (t == null) {
            if (ex == null)
                ex = new NullPointerException();
        }
        else if (i != 0)
            t.fork();
    ...
}
ForkJoinWorkerThread
具有以下方法:

final void More execTask(ForkJoinTask<?> t) {
    currentSteal = t;
    for (;;) {
       if (t != null)
           t.doExec();
    ...
}

是的,每次创建新的SortTask对象时,都会调用compute()方法,因为该方法在ForkJoinPool中分叉一组任务,而ForkJoinPool隐式地为每个任务调用compute

方法invoke()在语义上等价于fork();join()但始终尝试在当前线程中开始执行

文件中还包括:

通常,一个具体的ForkJoinTask子类(RecursiveAction/RecursiveTask)声明包含在构造函数中建立的参数的字段,然后定义一个compute方法,该方法以某种方式使用这个基类提供的控制方法

这里用于对它们进行排序的方法实际上是递归地对它们进行划分,当它们达到阈值时,它们将按顺序进行排序,在它们排序后,使用merge方法对它们进行合并。看看这个类似的例子:

class SortTask extends RecursiveAction {
final long[] array; final int lo; final int hi;
SortTask(long[] array, int lo, int hi) {
this.array = array; this.lo = lo; this.hi = hi;
}
protected void compute() {
 if (hi - lo < THRESHOLD)
   sequentiallySort(array, lo, hi);
  else {
   int mid = (lo + hi) >>> 1;
    coInvoke(new SortTask(array, lo, mid),
            new SortTask(array, mid+1, hi));
   merge(array, lo, hi);
       }
return null;
}
}
类SortTask扩展了递归操作{
final long[]数组;final int lo;final int hi;
SortTask(长[]数组,int-lo,int-hi){
this.array=array;this.lo=lo;this.hi=hi;
}
受保护的void compute(){
中频(高-低<阈值)
顺序排序(数组、lo、hi);
否则{
int mid=(低+高)>>>1;
coInvoke(新Sortask(阵列、lo、mid),
新的SortTask(数组,mid+1,hi));
合并(数组、lo、hi);
}
返回null;
}
}

当这里分叉两个任务,并在
isDone
对这两个任务都有效时返回。

是的,每次创建新的SortTask对象时,都会调用compute()方法,因为该方法分叉ForkJoinPool中的一组任务,而ForkJoinPool隐式地为每个任务调用compute

方法invoke()在语义上等价于fork();join()但始终尝试在当前线程中开始执行

文件中还包括:

通常,一个具体的ForkJoinTask子类(RecursiveAction/RecursiveTask)声明包含在构造函数中建立的参数的字段,然后定义一个compute方法,该方法以某种方式使用这个基类提供的控制方法

这里用于对它们进行排序的方法实际上是递归地对它们进行划分,当它们达到阈值时,它们将按顺序进行排序,在它们排序后,使用merge方法对它们进行合并。看看这个类似的例子:

class SortTask extends RecursiveAction {
final long[] array; final int lo; final int hi;
SortTask(long[] array, int lo, int hi) {
this.array = array; this.lo = lo; this.hi = hi;
}
protected void compute() {
 if (hi - lo < THRESHOLD)
   sequentiallySort(array, lo, hi);
  else {
   int mid = (lo + hi) >>> 1;
    coInvoke(new SortTask(array, lo, mid),
            new SortTask(array, mid+1, hi));
   merge(array, lo, hi);
       }
return null;
}
}
类SortTask扩展了递归操作{
final long[]数组;final int lo;final int hi;
SortTask(长[]数组,int-lo,int-hi){
this.array=array;this.lo=lo;this.hi=hi;
}
受保护的void compute(){
中频(高-低<阈值)
顺序排序(数组、lo、hi);
否则{
int mid=(低+高)>>>1;
coInvoke(新Sortask(阵列、lo、mid),
新的SortTask(数组,mid+1,hi));
合并(数组、lo、hi);
}
返回null;
}
}

When here分叉两个任务,并在
isDone
对这两个任务都有效时返回。

如果列表低于阈值,则不会创建额外的排序任务。否则,至少会创建额外的SortTask对号(2、4、6、8…)。如果列表低于阈值,则不会创建额外的SortTask。否则,至少会创建一个额外的SortTask对号(2、4、6、8…)。在compute()中调用invokeAll,而compute()则不会显式调用。所以,我再一次想知道,是否每次创建SortTask对象时都会调用compute(),或者不是这样。要开始计算,您应该调用
newforkjoinpool().invoke(new SortTask(data))
Compute不是构造函数的一部分,但它在递归动作类实例化后被调用<代码>注意
每当扩展RecursiveAction时,都必须实现compute方法。但他的问题是它是否被调用,而不是它是否是它的一部分。让我们把任务分成100个部分。我们调用
pool=newforkjoinpool(Task)
,然后调用
pool.shutdownNow()
,在这种情况下,不会为所有子任务调用compute。在compute()中调用invokeAll,而在compute()中不会显式调用compute()。所以,我再一次想知道,是否每次创建SortTask对象时都会调用compute(),或者不是这样。要开始计算,您应该调用
newforkjoinpool().invoke(new SortTask(data))
Compute不是构造函数的一部分,但它在递归动作类实例化后被调用<代码>注意
每当扩展RecursiveAction时,都必须实现compute方法。但他的问题是它是否被调用,而不是它是否是它的一部分。让我们有一个可以解决的任务