首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场

多线程
EN

Stack Overflow用户
提问于 2013-05-08 07:29:02
回答 2查看 457关注 0票数 5

我尝试在Java中创建一个并行的快速排序,我认为这是一个简单的方法(因为我还没有研究过接口执行器等等)

我需要一种打印排序数组的方法,一旦所有线程都是done..but,我不知道我将预先拥有多少线程。因此,我这样做的方式,它将等待每次使用联接()方法。因此,被调用的第一个联接方法必须等到所有其他线程都完成。对吧?

这样,当我在main() (打印数组)中执行最后两行时,我可以确保我的所有线程都完成了.

所以我有两个问题。

  1. 它是一个并行运行的多线程程序,对吗?还是我犯了一些错误,它实际上是以线性的方式运行,一个线程接着一个线程?
  2. 在主方法中显示排序数组的解决方案正确吗?

这是我的代码:

代码语言:javascript
运行
复制
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);
        }
    }
}
EN

回答 2

Stack Overflow用户

发布于 2013-05-08 11:04:43

如果我们知道线程的总数,就可以使用与线程数一起初始化的CountDownLatch。但是由于我们不知道线程的数量,我们需要一个扩展的CountDownLatch,它允许在计数器创建后增加计数器。不幸的是,我们不能仅仅扩展类CountDownLatch,因为底层计数器是私有的。一种方法是复制CountDownLatch的原始代码,以访问基础计数器。较少冗长的方式是扩展信号量以获得对reducePermits方法的访问,就像在可还原信号量中那样。原则上,CountDownLatch和信号量是相似的工具,但对内部计数器的解释不同:首先计算否决权,后者计算许可。

整个想法是在创建或启动线程时减少允许的数量,在方法run()的末尾减少允许在线程完成时的释放许可。许可的初始数量为1,因此如果没有线程启动,则主过程可以自由完成。注意,在run()方法开始时减少许可证的数量已经太迟了。

要获得真正好的工作代码,您还需要使用一个线程池和固定数量的线程,并对小数组进行顺序排序。

票数 3
EN

Stack Overflow用户

发布于 2013-05-08 11:34:47

线程的行为方式取决于硬件。在单核CPU和没有超线程的情况下,计算机在循环中逐行地处理一个线程。如果您有超线程和/或多核,它们可以同时运行多个行。对examplethread.join()的调用使调用线程等待直到example线程完成其任务(通过从run()方法返回)。如果您创建一个线程,并在2行之后调用join,那么您的多线程同步任务将非常类似于使其为单线程。

Id建议创建一个ArrayList并将每个线程添加到列表中,在设置了所有线程并运行之后,您将调用

代码语言:javascript
运行
复制
for(Thread t : mythreadlist) {
    try {
        t.join();
    } catch (InterruptedException e) { System.err.println("Interrupted Thread"); } 
} 

使应用程序等待所有线程退出。

编辑:

代码语言:javascript
运行
复制
// [...]
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);  
    }
}
// [...]
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16435037

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档