簡體   English   中英

如何在Java Fork-Join多線程程序中合並數組?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM