[英]How to merge arrays in Java Fork-Join multithreaded program?
我建立了一个中值过滤器,基本上它做了什么,它将获取一个元素数组,对其进行过滤并返回一个过滤后的数组。 现在,顺序版本可以完美运行,但是在尝试创建Fork-Join版本时,对于大于顺序阈值的数组,我无法获得任何结果,并且还伴随有ArrayIndexOutOfBounds错误。
现在,我不确定我要去哪里,经过数小时围绕Google和SO的研究之后,我放弃了,决定在此处发布问题。
这是我的代码片段,按顺序进行过滤:
//Filter Algorithm.
private void filter(BigDecimal[] elements, int shoulder) {
//Add boundary values in beginning
for(int i=0; i<shoulder; i++){
filteredElements[i] = elements[i];
}
//Add boundary values at end
for(int i=arraySize-1; i>((arraySize-1) - shoulder); i--){
filteredElements[i] = elements[i];
}
//Add middle values to filteredElements array
for (int i = shoulder; i < elements.length-shoulder; i++) {
BigDecimal[] windowValue = prepareWindow(elements, shoulder, filterSize);
BigDecimal median = getMedian(windowValue);
filteredElements[i] = median;
}
}
/*
* Pre-condition: Get Windowed Array
* Post-Condition: Return Median
*/
private static BigDecimal getMedian(BigDecimal[] windowValue) {
Arrays.sort(windowValue);
return windowValue[(filterSize-1)/2];
}
/*
* Pre-condition: Get elements array, get shoulder value and length of filterSize. Notice that this is given name windowLength.
* Post-Condition: Return Windowed Array
*/
private static BigDecimal[] prepareWindow(BigDecimal[] elements, int shoulder, int windowLength) {
BigDecimal[] out = new BigDecimal[windowLength];
int outCounter = 0;
for(int i = position; i<position+filterSize; i++){
out[outCounter] = elements[i];
outCounter++;
}
position++;
return out;
}
//Return Filtered Array
public BigDecimal[] getFilteredArray(){
return filteredElements;
}
现在,如果数组大于顺序阈值,则在Fork-Join中应用的相同顺序代码将不起作用,我想知道我在哪里出错。
这是我的Parallel实现的代码片段:
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.concurrent.RecursiveTask;
public class Parallel extends RecursiveTask<BigDecimal[]>{
BigDecimal[] elements;
BigDecimal[] filteredElements; //Array that contains the filtered elements
int shoulder;
static int filterSize;
int begin;
int end;
static int position = 0;
static final int SEQUENTIAL_CUTOFF = 4;
public Parallel(BigDecimal[] elements, int filterSize, int begin, int end) {
this.elements = elements;
Parallel.filterSize = filterSize;
this.begin = begin;
this.end = end;
filteredElements = new BigDecimal[elements.length]; //Array that contains the filtered elements
shoulder = (filterSize - 1) / 2;
}
@Override
protected BigDecimal[] compute() {
if (end - begin <= SEQUENTIAL_CUTOFF) {
filter(elements, shoulder); //Run Filter Method
}else{
Parallel curLeft = new Parallel(elements, filterSize, this.begin, ((this.begin+this.end)/2));
Parallel curRight = new Parallel(elements, filterSize, ((this.begin+this.end)/2), this.end);
curLeft.fork();
curRight.compute();
curLeft.join();
}
return filteredElements;
}
//Filter Algorithm.
private void filter(BigDecimal[] elements, int shoulder) {
//Add boundary values in beginning
for(int i=0; i<shoulder; i++){
filteredElements[i] = elements[i];
}
//Add boundary values at end
for(int i=this.elements.length-1; i>((this.elements.length-1) - shoulder); i--){
filteredElements[i] = elements[i];
}
//Add middle values to filteredElements array
for (int i = shoulder; i < elements.length-shoulder; i++) {
BigDecimal[] windowValue = prepareWindow(elements, shoulder, filterSize);
BigDecimal median = getMedian(windowValue);
filteredElements[i] = median;
}
}
/*
* Pre-condition: Get Windowed Array
* Post-Condition: Return Median
*/
private static BigDecimal getMedian(BigDecimal[] windowValue) {
Arrays.sort(windowValue);
return windowValue[(filterSize-1)/2];
}
/*
* Pre-condition: Get elements array, get shoulder value and length of filterSize. Notice that this is given name windowLength.
* Post-Condition: Return Windowed Array
*/
private static BigDecimal[] prepareWindow(BigDecimal[] elements, int shoulder, int windowLength) {
BigDecimal[] out = new BigDecimal[windowLength];
int outCounter = 0;
for(int i = position; i<position+filterSize; i++){
out[outCounter] = elements[i];
outCounter++;
}
position++;
return out;
}
//Return Filtered Array
public BigDecimal[] getFilteredArray(){
return filteredElements;
}
}
基本上,Parallel实现使用我制作的顺序方法,但是我无法使其正常工作。 以下是我得到的错误列表(我添加了引起错误的行,使阅读更容易。大多数错误在顺序方法中,我不明白为什么):
Caused by: java.lang.ArrayIndexOutOfBoundsException: 8
at Parallel.prepareWindow(Parallel.java:80) > out[outCounter] = elements[i];
at Parallel.filter(Parallel.java:55) > BigDecimal[] windowValue = prepareWindow(elements, shoulder, filterSize);
at Parallel.compute(Parallel.java:29) > filter(elements, shoulder); //Run Filter Method
at Parallel.compute(Parallel.java:34) > curRight.compute();
如果有人可以提供有意义的答案,我们将不胜感激。
谢谢。
我们看不到整个代码,但是我看到以某种方式并行调用了两个compute(),并且它们同时调用了prepareWindow()。
最大的问题是position
是一个静态变量,并且两个线程都在递增相同的引用,从而超出了范围。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.