Java - 螺纹基数排序

时间:2012-12-17 20:28:16

标签: java multithreading sorting radix

我一直在研究Radix Sort的不同变体。起初我使用链接,这非常慢。然后我在使用val%(10 * pass)时使用了计数排序,并且最近将其转换为相应的字节并对它们进行排序,这使得我也可以按负值排序。

我想尝试使用多线程,并且只能在大约一半的时间内完成它。我想知道是否有人可以帮助查看我的代码,看看我在哪里遇到线程问题。我有每个线程计数每个字节排序。感谢:

public class radixSort {

    public int[] array;
    public int arraySize, arrayRange;
    public radixSort (int[] array, int size, int range) {
        this.array = array;
        this.arraySize = size;
        this.arrayRange = range;
    }
    public int[] RadixSort() {
        Thread[] threads = new Thread[4];
        for (int i=0;i<4;i++)
            threads[i] = new Thread(new Radix(arraySize, i));
        for (int i=0;i<4;i++)
            threads[i].start();
        for (int i=0;i<4;i++)
            try {
                threads[i].join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        return array;
    }
    class Radix implements Runnable {
        private int pass, size;
        private int[] tempArray, freqArray;
        public Radix(int size, int pass) {
            this.pass = pass;
            this.size = size;
            this.tempArray = new int[size];
            this.freqArray = new int[256];
        }
        public void run() {
            int temp, i, j;
            synchronized(array) {
                for (i=0;i<size;i++) {
                    if (array[i] <= 0) temp = array[i] ^ 0x80000000;
                    else temp = array[i] ^ ((array[i] >> 31) | 0x80000000);
                    j = temp >> (pass << 3) & 0xFF;
                    freqArray[j]++;
                }
                for (i=1;i<256;i++)
                    freqArray[i] += freqArray[i-1];
                for (i=size-1;i>=0;i--) {
                    if (array[i] <= 0) temp = array[i] ^ 0x80000000;
                    else temp = array[i] ^ ((array[i] >> 31) | 0x80000000);
                    j = temp >> (pass << 3) & 0xFF;
                    tempArray[--freqArray[j]] = array[i];
                }
                for (i=0;i<size;i++)
                    array[i] = tempArray[i];
            }
        }
    }
}

3 个答案:

答案 0 :(得分:2)

这种方法存在一个基本问题。要从多线程中获益,您需要为每个线程提供与其他线程相比不重叠的任务。通过synchonizing array,你已经做到了,所以一次只有一个线程可以正常工作,这意味着你得到线程的所有开销而没有任何好处。

考虑分区任务的方法,以便线程并行工作。例如,在第一次传递之后,具有1个高位的所有项目将在阵列的一个部分中,而具有零个高位的项目将在另一个部分中。您可以在阵列的每个部分上运行一个线程而不进行同步。

请注意,您的runnable必须完全更改,以便它在数组的指定子集中执行一次传递,然后为下一次传递生成线程。

答案 1 :(得分:0)

除了错误的类和方法名称(类应该以大写字母开头,方法不应该),我可以看到你正在同步数组上的所有线程工作。所以它实际上根本不是平行的。

答案 2 :(得分:0)

我很确定你无法真正并行化RadixSort,至少在你尝试的方式上如此。有人指出你可以通过分而治之的方式来做到这一点,因为你首先按最高位排序,但事实上,RadixSort首先通过比较低位来工作,所以你不能真正分而治之。每次通过后,阵列基本上可以完全置换。

伙计们,证明我错了,但我认为像你想的那样并行化这个算法是不可能的。也许你可以并行化每次传递内部完成的(计数)排序,但要注意++不是原子操作。

相关问题