[英]Trying to parallelize quicksort to run on multiple threads in Java
我有一個快速排序算法,可以很好地工作,但是當我嘗試並行化時,僅對數組的后半部分進行了排序,而另一半幾乎沒有變化。 而且由於我是並行編程的新手,所以我不知道為什么。 我擁有的解決方案是從在線找到的不同代碼中組合而成的。 如何改進它以便對整個數組進行排序?
public class foo {
private static final int N_THREADS = Runtime.getRuntime().availableProcessors();
private static final int FALLBACK = 2;
private static Executor pool = Executors.newFixedThreadPool(N_THREADS);
public static <T extends Comparable<T>> void sort(int[] numberArray){
if(numberArray == null && numberArray.length == 0){
return;
}
final AtomicInteger count = new AtomicInteger(1);
pool.execute(new QuicksortRunnable<T>(numberArray, 0, numberArray.length-1, count));
}
private static class QuicksortRunnable<T extends Comparable<T>> implements Runnable {
private final int[] values;
private final int left;
private final int right;
private final AtomicInteger count;
public QuicksortRunnable(int[] values, int left, int right, AtomicInteger count) {
this.values = values;
this.left = left;
this.right = right;
this.count = count;
}
@Override
public void run() {
quicksort(left, right);
synchronized (count) {
if (count.getAndDecrement() == 1)
count.notify();
}
}
private void quicksort(int pLeft, int pRight) {
int pivotIndex = (pRight - pLeft) / 2 + pLeft;
int pivot = values[pivotIndex];
int j = pRight;
int i = pLeft;
while (i < j) {
while (values[i] > pivot) {
i++;
}
while (values[j] < pivot) {
j--;
}
if (i <= j) {
int temp = values[i];
values[i] = values[j];
values[j] = temp;
i++;
j--;
}
}
if (count.get() >= FALLBACK * N_THREADS) {
if (pLeft < j)
quicksort(pLeft, j);
if (i < pRight)
quicksort(i, pRight);
} else {
if (pLeft < j) {
count.getAndAdd(1);
pool.execute(new QuicksortRunnable<T>(values, pLeft, j, count));
}
if (i < pRight) {
count.getAndAdd(1);
pool.execute(new QuicksortRunnable<T>(values, i, pRight, count));
}
}
}
}
~~~
My main function:
public static void main(String[] arg) {
Random rand = new Random();
int length = 1000;
int[] toSort = new int[length];
for(int i = 0; i<length; i++){
toSort[i] = rand.nextInt(length);
}
sort(toSort);
boolean sortedFH = true;
boolean sortedSH = true;
for(int i = 0; i<length/2; i++) {
if (toSort[i] < toSort[i + 1]) {
sortedFH = false;
}
}
for(int i = length/2; i<length-1; i++) {
if (toSort[i] < toSort[i + 1]) {
sortedSH = false;
}
}
System.out.println();
System.out.println("First half :" + sortedFH);
System.out.println("Second half :" + sortedSH);
}
}
Returns:
First half :false
Second half :true
編輯:刪除了程序的一部分。 我嘗試了一些東西,沒有用,在發布問題時忘記將其刪除。
首先,我認為您看到的結果主要是因為要在排序線程完成之前打印出結果。 您需要等待所有線程完成后才能檢查結果。
根據您的代碼,您可以使用AtomicInteger
計數輕松地完成此操作,以阻止sort()
返回,直到所有線程完成。
public static <T extends Comparable<T>> void sort(int[] numberArray) {
if (numberArray == null || numberArray.length == 0) {
return;
}
final AtomicInteger count = new AtomicInteger(1);
pool.execute(new QuicksortRunnable<T>(numberArray, 0, numberArray.length - 1, count));
while (count.get() > 0) {
synchronized (count) {
count.wait();
}
}
}
順便說一句,除非是有意的,否則您的算法似乎將以降序對數組進行排序。 我認為你需要翻轉
while (values[i] > pivot) {
i++;
}
while (values[j] < pivot) {
j--;
}
至
while (values[i] < pivot) {
i++;
}
while (values[j] > pivot) {
j--;
}
主方法末尾的檢查也是如此。
您對null或空數組的檢查應以OR而非AND分隔
if (numberArray == null || numberArray.length == 0) {
return;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.