多线程Mergesort问题

时间:2012-09-09 04:31:29

标签: java multithreading mergesort

我正在尝试编写一个多线程的mergesort,而我对我来说是非常令人困惑的问题。我不完全了解线程如何共享/使用变量的规则......

例如,如果在一个可运行的类中,我创建该Runnable的另一个实例并将其中一个数组作为参数传递给那个类进行转移的编辑吗?看起来好像他们这样做,但看起来好像我有意想不到的行为。

这是我的代码:

public class PSort implements Runnable {

private int [] Arr;
private int begin;
private int end;

public void run () {
    // Base Case - Insertion sort
    if(this.end-this.begin <= 10) {
        InsertionSort();
    }
    else {
        int left_start  = this.begin;
        int left_end    = this.begin + (this.end-this.begin)/2;
        int right_start = this.begin + (this.end-this.begin)/2 + 1;
        int right_end   = this.end;


        Thread t1 = new Thread(new PSort(this.Arr, left_start, left_end));
        Thread t2 = new Thread(new PSort(this.Arr, right_start, right_end));
        t1.start();
        t2.start();

        try {
            t1.join();
            t2.join();

            merge(left_start, left_end, right_start, right_end);
        } catch (Exception e) {}
    }
}

public PSort (int[] A, int begin, int end) {
    this.Arr = A;
    this.begin = begin;
    this.end = end;
    System.out.println("New thread: " + this.begin + " " + this.end);
}

public static void ParallelSort (int[] A, int begin, int end) {

    PSort psort = new PSort(A, begin, end);
    Thread thread = new Thread(psort);

    thread.start();

    try {
        thread.join();
        psort.printArray();
    } catch (InterruptedException e) {}
}

public void printArray() {
    int count = 0;
    for(int x = this.begin; x < this.end; x++) {
        if(count < 10) {
            System.out.print(Arr[x] + " ");
            count++;
        }
        else {
            count = 1;
            System.out.print("\n" + Arr[x] + " ");
        }
    }
}

private void InsertionSort () {
    for(int x = this.begin; x < this.end; x++) {
        int currentNum = this.Arr[x];
        int hole = x;
        while((hole > 0) && (this.Arr[hole-1] > currentNum)) {
            this.Arr[hole] = this.Arr[hole-1];
            hole = hole - 1;
        }
        this.Arr[hole] = currentNum;
    }
}

private void merge (int left_start, int left_end, int right_start, int right_end) {
    /*
    int length = right_end - left_start;

    int[] temp = new int[length];
    int leftP = left_start;
    int rightP = right_start;
    int index = 0;

    while((leftP <= left_end) && (rightP < right_end)) {
        if(Arr[leftP] < Arr[rightP]) {
            temp[index++] = Arr[leftP++];
        }
        else {
            temp[index++] = Arr[rightP++];
        }
    }   
    while(leftP <= left_end) {
        temp[index++] = Arr[leftP++];
    }
    while(rightP < right_end) {
        temp[index++] = Arr[rightP++];
    }

    System.arraycopy(temp, 0, Arr, left_start, length);
    */

}
}

现在,我正在使用填充了随机整数0-9的size-40数组调用PSort.ParallelSort,这是我得到的输出:

New thread: 0 40
New thread: 0 20
New thread: 21 40
New thread: 0 10
New thread: 11 20
New thread: 21 30
New thread: 31 40
0 1 1 2 2 2 6 7 7 8 
8 3 3 3 4 4 5 5 6 7 
9 2 3 3 3 4 7 8 9 9 
2 2 6 7 7 7 8 8 9 9 

请注意,我已经注释掉了例程中的“merge”部分,因此我希望每个输出行都能正确排序,但事实并非如此。我自己测试了InsertionSort,它似乎没有失败,所以在这里似乎有一些并发问题,我完全忽略了。

注意:我意识到这里有一些更严重的问题,因为较高的数字被加权到整个数组的最后两行,即使我没有合并......

1 个答案:

答案 0 :(得分:2)

该错误发生在您的InsertionSort方法中(顺便说一下,该方法应以小写字母开头):

int hole = x;
while ((hole > 0) && /* ... */) {
    // ...
    hole--;
}

所以你从x开始,这是在指定的段内,但是回到 0 ,所以所有线程最终写在相同的段上。是的,线程之间共享数据 ,这是多线程时的难点。