并发线程合并排序

时间:2015-10-25 14:39:09

标签: java multithreading concurrency mergesort

我必须编写并发Merge Sort Aplication的代码。每次数组被拆分时,我必须为右半部分创建一个新线程(最大线程数为5 - > 5次),继续Mergesort算法。

enter image description here

这是我的计划:

class Mergesorts implements Runnable{

    private int[] internal;

    Mergesorts(int[] arr) {
        internal = arr;
    }

    private void processCommand(int [] array) {
        if (array.length > 1) { 
            int[] left = leftHalf(array);
            int[] right = rightHalf(array);
            processCommand(left);
            processCommand(right);
            merge(array, left, right);
        }
    }

    public int[] rightHalf(int[] array) {
        int size1 = array.length / 2;
        int size2 = array.length - size1;
        int[] right = new int[size2];
        for (int i = 0; i < size2; i++) {
            right[i] = array[i + size1];
        }
        return right;
    }

    public void run() {
        processCommand(internal);
    }
}

如何重写我的代码以便如上所述同时进行排序?

如何编辑我的代码,以便它最多只创建5个线程而不是更多?

private void processCommand(int [] array) {
    if (array.length > 1) {


        int[] right = rightHalf(array);
        int[] left = leftHalf(array);


        Mergesorts worker2 = new Mergesorts(right);
        Thread s = new Thread(worker2);
        s.start();

        processCommand(left);

        try {
            s.join();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        merge(array, left, right);}

}

1 个答案:

答案 0 :(得分:0)

在processCommand()方法中启动新线程,而不是在rightHalf()方法中启动。如果你有线程可用,那么在right上构造一个新的Mergesorts对象而不是调用processCommand(右)的行,而是用它来启动一个线程。不要忘记在线程上调用join()以确保它在完成合并之前完成。

为了提高并行性,可以在处理数组的左半部分之前在数组的右半部分启动新线程,这样两者都可以同时完成 - 也就是说,将processCommand(left)移动到块之后要么执行processCommand(右),要么启动新线程。 join()调用应该在完成两半之后,但在合并之前。

编辑:你越来越近了;为了解决你的评论,你需要这样的东西:

private void processCommand(int [] array) {
    if (array.length <= 1)
        {return;}

    int[] left = leftHalf(array);
    int[] right = rightHalf(array);
    Thread rightThread = null;

    if (b <= 5) {
        ++b;
        Mergesorts worker = new Mergesorts(right);
        rightThread = new Thread(worker);
        rightThread.start();
    } else {
        processCommand(right);
    }

    processCommand(left);

    if (null != rightThread) {
        try {
            rightThread.join();
            b--
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            // better error handling would be good
        }
    }

    merge(array, left, right);
}

b也需要是volatile,以确保不同的线程可以看到当前正在执行的线程数。