我尝试在Java中创建一个并行的快速排序,我认为这是一个简单的方法(因为我还没有研究过接口执行器等等)
我需要一种打印排序数组的方法,一旦所有线程都是done..but,我不知道我将预先拥有多少线程。因此,我这样做的方式,它将等待每次使用联接()方法。因此,被调用的第一个联接方法必须等到所有其他线程都完成。对吧?
这样,当我在main() (打印数组)中执行最后两行时,我可以确保我的所有线程都完成了.
所以我有两个问题。
这是我的代码:
public class Main {
public static void main(String[] args) {
ArrayList<Integer> array = new ArrayList();
//please assume that I have invoked the input for the array from the user
QuickSortWithThreads obj = new QuickSortWithThreads(array,0 ,array.size()-1 );
for(int i = 0; i < array.size(); i++)
System.out.println(array.get(i));
}
}
public class QuickSortWithThreads {
public QuickSortWithThreads(ArrayList <Integer> arr, int left, int right){
quicksort(arr, left, right);
}
static void quicksort(ArrayList <Integer> arr, int left, int right) {
int pivot;
if(left<right){
pivot = partition(arr, left, right);
QuickSortThread threadLeftSide = new QuickSortThread(arr, pivot + 1, right);
threadLeftSide.start();
quicksort(arr, left, pivot - 1);
try {
threadLeftSide.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
static int partition(ArrayList<Integer> arr, int left, int right) {
int pivot = arr.get(right);
int i = left -1;
for( int j = left; j <= right - 1; j++) {
if (arr.get(j) <= pivot){
i = i + 1;
exchange(arr, i, j);
}
}
exchange(arr, i + 1, right);
return i + 1;
}
static void exchange(ArrayList<Integer> arr, int i, int j) {
int swap = arr.get(i);
arr.set(i, arr.get(j));
arr.set(j, swap);
}
private static class QuickSortThread extends Thread {
int right;
int left;
ArrayList<Integer> refArray;
public QuickSortThread(ArrayList<Integer> array, int left, int right) {
this.right = right;
this.left = left;
refArray = new ArrayList<Integer>();
refArray = array;
}
public void run() {
quicksort(refArray, left, right);
}
}
}发布于 2013-05-08 11:04:43
如果我们知道线程的总数,就可以使用与线程数一起初始化的CountDownLatch。但是由于我们不知道线程的数量,我们需要一个扩展的CountDownLatch,它允许在计数器创建后增加计数器。不幸的是,我们不能仅仅扩展类CountDownLatch,因为底层计数器是私有的。一种方法是复制CountDownLatch的原始代码,以访问基础计数器。较少冗长的方式是扩展信号量以获得对reducePermits方法的访问,就像在可还原信号量中那样。原则上,CountDownLatch和信号量是相似的工具,但对内部计数器的解释不同:首先计算否决权,后者计算许可。
整个想法是在创建或启动线程时减少允许的数量,在方法run()的末尾减少允许在线程完成时的释放许可。许可的初始数量为1,因此如果没有线程启动,则主过程可以自由完成。注意,在run()方法开始时减少许可证的数量已经太迟了。
要获得真正好的工作代码,您还需要使用一个线程池和固定数量的线程,并对小数组进行顺序排序。
发布于 2013-05-08 11:34:47
线程的行为方式取决于硬件。在单核CPU和没有超线程的情况下,计算机在循环中逐行地处理一个线程。如果您有超线程和/或多核,它们可以同时运行多个行。对examplethread.join()的调用使调用线程等待直到example线程完成其任务(通过从run()方法返回)。如果您创建一个线程,并在2行之后调用join,那么您的多线程同步任务将非常类似于使其为单线程。
Id建议创建一个ArrayList并将每个线程添加到列表中,在设置了所有线程并运行之后,您将调用
for(Thread t : mythreadlist) {
try {
t.join();
} catch (InterruptedException e) { System.err.println("Interrupted Thread"); }
} 使应用程序等待所有线程退出。
编辑:
// [...]
public class QuickSortWithThreads {
ArrayList<QuickSortThread> threads = new ArrayList<>();
public QuickSortWithThreads(ArrayList <Integer> arr, int left, int right){
quicksort(arr, left, right); // Pretty much make your threads start their jobs
for(Thread t : threads) { // Then wait them to leave.
try {
t.join();
} catch (InterruptedException e) { System.err.println("Interrupted Thread"); }
}
}
// [...]
static void quicksort(ArrayList <Integer> arr, int left, int right) {
int pivot;
if(left<right){
pivot = partition(arr, left, right);
QuickSortThread threadLeftSide = new QuickSortThread(arr, pivot + 1, right);
threadLeftSide.start();
threads.add(threadLeftSide());
//
quicksort(arr, left, pivot - 1);
}
}
// [...]https://stackoverflow.com/questions/16435037
复制相似问题