【问题标题】:wait for all threads complete in Java等待Java中的所有线程完成
【发布时间】:2015-04-17 14:17:20
【问题描述】:

我使用来自 cern.colt.ParallelQuickSort 库(http://incanter.org/docs/parallelcolt/api/cern/colt/ParallelQuickSort.html 和 https://github.com/Danimoth/Parallel-Colt/blob/master/src/cern/colt/ParallelQuickSort.java)的多线程快速排序 Java 函数。我想测试选择不同数量的线程时经过了多少时间。我使用 System.nanoTime() 来跟踪运行时间。但是,即使我选择的线程数和未排序的数组多次运行相同,运行时间也有很大不同。我认为这是因为 cern.colt.ParallelQuickSort 库中提供的 quicksort() 没有等待线程完成。我想知道如何编写代码来等待所有线程完成,以便我可以测量库提供的函数之外的运行时间?像下面这样:?

ParallelQuickSort qs=new ParallelQuickSort();
long startTime = System.nanoTime();
qs.quickSort(unsorted_array, 0, array_size, comp, number_threads);

//java code to wait for all threads to complete

long time_elapse= System.nanoTime() - startTime;

编辑: 下面是我的代码: 最初,我的代码是针对数组大小为 2^10、2^15、2^20、2^25 和 2^28 的线程数从 1 到 15 运行快速排序,并且对于每种情况我运行 30 次。为了调试,我将代码更改为仅使用 1 个线程运行 array size=2^10 并运行 10 次。

import cern.colt.ParallelQuickSort;
import cern.colt.function.tint.IntComparator;
import cern.colt.Timer;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.System.*;
import java.util.*;


public class quick_sort {

    static void readData(int dst[], int nitems, int num) throws IOException{ 
        String s="mydata"+Integer.toString(num)+".txt";
        //System.out.println(s);
        Scanner scanner = new Scanner(new File(s));
        int i = 0;
        while(scanner.hasNextInt())
        {
            dst[i++] = scanner.nextInt();
        }

    }



public static void main(String [ ] args) throws IOException
{

    //for(int i=0; i<n;i++) dst[i]=n-i;


    /*
    System.out.println("Unsorted: ");
    for(int i=0; i<n; i++) System.out.print(dst[i]+" ");
    System.out.println(" ");
    */

    IntComparator comp=new IntComparator(){
        public int compare(int a, int b){
            if(a>b) return 1;
            else if(a<b) return -1;
            else return 0;
        }
      };




    int iter=10;
    int thread_num=1;
    //FileWriter fw = new FileWriter("out.txt");

    int num[]={10, 15, 20, 25, 28};
for(int m=0; m<1; m++){         
    for(int k=1; k<=thread_num; k++){
    long estimatedTime=0;
    for(int i=0; i<iter; i++){
        int n=1<<num[m];
        int dst[]=new int[n];
        readData(dst, n, num[m]);

        ParallelQuickSort qs=new ParallelQuickSort();

        long startTime = System.nanoTime();

        qs.quickSort(dst, 0, n, comp, k);

        long temp= System.nanoTime() - startTime;
        estimatedTime+=temp;



        System.out.println("Time="+temp*0.000001);

    }
    System.out.println(num[m]+"Wall Clock Time when thread number="+k+": "+estimatedTime/iter*0.000001);
    //fw.write(num[m]+"Wall Clock Time when thread number="+k+": "+estimatedTime/iter*0.000001+'\n');
}   


    //System.out.println("Sorted: ");
    //for(int i=0; i<n; i++) System.out.print(dst[i]+" ");
    //System.out.println(" ");




}
//fw.close();
System.out.println("Finish!");

}   

}

结果如下图:

Time=0.755289
Time=0.632124
Time=0.502016
Time=0.502922
Time=0.100524
Time=0.076072
Time=0.073657
Time=0.073355
Time=0.074261
Time=0.076374
10Wall Clock Time when thread number=1: 0.286659
Finish!

【问题讨论】:

  • docs.oracle.com/javase/7/docs/api/java/lang/… - 希望这会有所帮助。
  • 我无法获取该函数中创建的线程,如何使用join?
  • 使用ExecutorService
  • 您确实应该使用CountDownLatch。定义一个CountDownLatch,其大小等于线程数,countDownLatch.countdown()在每个线程中,countDownLatch.await()等待每个线程。
  • 如果使用CountDownLatch,是否需要更改库代码? ParallelQuickSort.java 是库代码,我认为我无法更改它。

标签: java multithreading


【解决方案1】:

函数ParallelQuickSort.quicksort 仅在所有线程/子操作完成后返回。您无需手动等待所有线程完成。

这可以通过查看代码来确认(查找other.get()),这是唯一合理的行为。

编辑:测试性能可能非常困难,请参阅Java Performance Testing 和许多其他地方了解详细信息。

【讨论】:

  • 那为什么在相同的条件下(即相同的未排序数组,相同的线程数)运行多次例如30次。我得到的运行时间有很大的不同?
  • @weidan 这可能是多种因素,可能是您电脑上运行的其他进程。我已经更新了我的答案。如果您想要更准确的答案,请尝试使用更大的数组/更多迭代或发布您的测试代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-09-20
  • 1970-01-01
  • 1970-01-01
  • 2011-06-09
  • 1970-01-01
  • 2021-03-30
相关资源
最近更新 更多