gpt4 book ai didi

java - 尝试并行化快速排序以在Java中的多个线程上运行

转载 作者:太空宇宙 更新时间:2023-11-04 09:26:48 24 4
gpt4 key购买 nike

我有一个运行良好的快速排序算法,但是当我尝试并行化时,仅对数组的后半部分进行排序,另一半几乎没有变化。由于我是并行编程的新手,我不知道为什么。我的解决方案是根据网上找到的不同代码组合而成的。如何改进它以使整个数组排序?

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;
}

关于java - 尝试并行化快速排序以在Java中的多个线程上运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57590968/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com