簡體   English   中英

嘗試並行化quicksort以在Java中的多個線程上運行

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

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