Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/344.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 并行化对数组中每个元素的递归函数调用(使用ForkJoinPool)_Java_Arrays_Multithreading_Recursion_Concurrency - Fatal编程技术网

Java 并行化对数组中每个元素的递归函数调用(使用ForkJoinPool)

Java 并行化对数组中每个元素的递归函数调用(使用ForkJoinPool),java,arrays,multithreading,recursion,concurrency,Java,Arrays,Multithreading,Recursion,Concurrency,考虑以下场景: public void processArray(int a, SomeType array) { for (int i = 0; i < array.length; ++i) { recFunction(a, array[i]); } } private void recFunction(int a, SomeType element){ ... recFunction(a + x, element); rec

考虑以下场景:

public void processArray(int a, SomeType array) {
    for (int i = 0; i < array.length; ++i) {
        recFunction(a, array[i]);
    }
}
private void recFunction(int a, SomeType element){
     ...
     recFunction(a + x, element);
     recFunction(a + y, element);
     ...
}
public void processArray(int a,SomeType数组){
对于(int i=0;i
processArray对数组的每个元素调用recFunction。如何使用Java创建此程序的并行版本?请注意,要处理的数组可能非常大(最多10000个元素)。我的第一个想法是使用ForkJoinPool,但我绝对不能为每个数组元素创建RecursiveTask,因为这将创建10000个新对象


另外,我必须处理不同的数组,因此必须调用processArray几次。我希望避免每次创建新线程,而是使用现有线程。您知道如何使用Executor或ForkJoinPool实现吗?

这是一个快速排序示例,无论如何都不是最优的,但应该为您提供与递归版本进行比较的基础

import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;

public class ParallelSort {
    // default, Creates a ForkJoinPool with parallelism equal to Runtime.availableProcessors()
    private ForkJoinPool pool = new ForkJoinPool();

    public void sort(int[] elements) {
        pool.invoke(new SortAction(elements, 0, elements.length-1));
    }

    public class SortAction extends RecursiveAction {
        private static final long serialVersionUID = 3060427288506544983L;

        final int[] elements;
        int low;
        int high;

        SortAction(int[] elements, int low, int high) {
            this.elements = elements;
            this.low = low;
            this.high = high;
        }

        protected void compute() {
            if (low < high) {
                int pivotIndex = (low + high) >>> 1;
                pivotIndex = partition(pivotIndex);

                invokeAll(new SortAction(elements, low, pivotIndex - 1),
                          new SortAction(elements, pivotIndex + 1, high));
            }
        }

        private int partition(int pivotIndex) {
            int pivotValue = elements[pivotIndex];

            swap(elements, pivotIndex, high);
            int storeIndex = low;

            for (int i = low; i < high; i++) {
                if (elements[i] < pivotValue) {
                    swap(elements, i, storeIndex);
                    storeIndex++;
                }
            }

            swap(elements, storeIndex, high);
            return storeIndex;
        }

        private void swap(int[] elements, int i, int j) {
            if (i != j) {
                int temp = elements[i];
                elements[i] = elements[j];
                elements[j] = temp;
            }
        }
    }
}
import java.util.concurrent.ForkJoinPool;
导入java.util.concurrent.RecursiveAction;
公共类并行排序{
//默认情况下,创建并行度等于Runtime.availableProcessors()的ForkJoinPool
私有ForkJoinPool池=新的ForkJoinPool();
公共void排序(int[]元素){
invoke(新的排序(elements,0,elements.length-1));
}
公共类SortAction扩展了RecursiveAction{
私有静态最终长serialVersionUID=306042728856544983L;
最终int[]元素;
int低;
int高;
排序(int[]元素,int低位,int高位){
这个元素=元素;
这个.低=低;
这个高=高;
}
受保护的void compute(){
如果(低<高){
int pivotIndex=(低+高)>>>1;
数据透视索引=分区(数据透视索引);
invokeAll(新排序(元素,低位,数据透视索引-1),
新排序(元素,数据透视索引+1,高);
}
}
专用整型分区(整型数据透视索引){
int pivotValue=元素[pivotIndex];
交换(元素、数据透视索引、高);
int storeIndex=低;
对于(int i=低;i<高;i++){
if(元素[i]<数据透视值){
交换(元素、i、存储索引);
storeIndex++;
}
}
交换(元素、存储索引、高);
返回存储索引;
}
私有无效交换(int[]元素,int i,int j){
如果(i!=j){
int temp=元素[i];
元素[i]=元素[j];
元素[j]=温度;
}
}
}
}
一些简要说明:

  • 您不需要在sort类中声明ForkJoinPool,我只是在这里这样做,以便调用方不必考虑池

  • 一旦分区大小变小,这种快速排序如果返回到串行排序,性能会更好。我在这里不在乎这个


这在数百万个元素上运行没有问题。

是否可以拆分阵列。例如,创建4个线程,每个线程计算数组的一半?还是元素相互依存?这项任务真的值得平行化吗?另外,我认为ForkJoinTask可以通过ForkJoinPool进行扩展。一个任务将创建多少个新任务?(可能是完成后的问题?)10k阵列太小,无法并行,10m是一个候选阵列。然后,按照JavaDoc中的示例分解数组。当达到阈值时,对大数组的一段调用ProcessArray(),并将结果连接到链上。@edharned:如果处理一个元素需要花费很多时间,则可以进行并行分析。@OP true。然后按照JavaDoc中的分解示例或StackOverflow上的许多示例进行操作。创建10k
RecursiveTask
对象的开销非常低,但是,其他注释是有效的:您不会使用单个元素(也就是说,您无论如何都会以1000个任务结束,每个任务处理10个元素左右),到目前为止,函数是递归的这一事实是否是使用fork-join池的原因还不清楚。您真的应该提到上面的源代码以及指向它的链接,@javadba Quicksort在所有算法书籍中都几乎相同(fork-joinpool示例也是如此)。另外要注意的是,如果你把一个LinkedList传给这个网站,那么这个网站的例子会在一个列表上排序,这是非常糟糕的。而且,如果你想学究的话,这些都是同样有影响力的:而且(你链接的作者显然遵循后者的伪代码,顺便说一句,一直到“storeIndex”的名字)