多线程产生多个线程以及如何等待子线程

时间:2013-10-07 03:04:38

标签: java multithreading executorservice java.util.concurrent

我有两个数组abc[100]def[1000],我必须找到一个数组xyz[100],其中xyz[i] = minDistance(abc[i],def)abc中的每个元素我必须在def中找到相应的最近元素,并在xyz.

中设置

为此,我使用两级线程。在第一级,我在abc中为每10个点创建线程,在每个10点创建线程,我在def.每100个点创建子线程。下面是我的实现。

我的问题是

  • 如何等待abc(即def个线程)的子线程。我已经完成了java连接方法,但无法弄清楚如何使用它。

  • 在这种情况下我可以使用循环屏障。

  • abc的实际数据大小为1000,def的实际数据为10000,我之前没有使用过线程,因此这个实现可能会出现任何问题。我也看到在某些示例中使用了ThreadPoolExecutor而不是FixedThreads,但无法确定ThreadPoolExecutor会有多少。

1。 DistanceCalculation

public class MinDistanceCalculation {   
public static List<double[]> xyz = new Vector<double[]>(); 

public void method1(){      
    double[][] abc = new double[100][7];
    double[][] def = new double[1000][7];

    ExecutorService executorService = Executors.newFixedThreadPool(10);     
    for(int i = 0 ; i < abc.length ; i = i*10){
        executorService.execute(new MainThread(abc,i , i*10 , def));
    }       
}
}

2。主线程/ abc线程

public class MainThread implements Runnable{

double[][] abc = null;
double[][] def = null;
int startPos  = 0;
int endPos = 0;

public MainThread(double[][] abc , int startPos , int endPos, double[][] def){
    this.abc = abc;
    this.def = def;
}

@Override
public void run() {     

    for(int i = startPos ; i < endPos ; i++){
ExecutorService executorService = Executors.newFixedThreadPool(10);
List<Future<double[]>>  minDistancePoints = new ArrayList<Future<double[]>>();

for(int j = 0 ; j < def.length ; j = j*100 ){
  Future<double[]> minDistancePoint = null;
  minDistancePoint = executorService.submit(new ChildThread(abc[i], def, j, j*100));
  minDistancePoints.add(minDistancePoint);              
        }
 // How can I wait for all the threads and calculate the MinDistance and 
        //add it to the actual array
        findMinDistanceOfAll(abc[i],minDistancePoints);
                    executorService.shutdown();
    }       
}

public void findMinDistanceOfAll(double[] mainPoint, List<Future<double[]>>  distancePoints){
    // Here  I will find the min among the given points and add it actual array.
    MinDistanceCalculation.xyz.add(null);
}

}

子线程/ def线程

public class ChildThread implements Callable<double[]> {

double[] abc = null;
double[][] def = null;
int from;
int to;

public ChildThread(double[] abc, double[][] def, int from, int to) {
    this.def = def;
    this.abc = abc;
    this.from = from;
    this.to = to;
}

@Override
public double[] call() throws Exception {

    double minDistance = Double.MAX_VALUE;
    double currentDistance = 0;
    double[] minCandidate = null;

    for (int i = from; i < to; i++) {
        currentDistance = distance(abc,def[i]);
        if (currentDistance < minDistance) {
            minDistance = currentDistance;
            minCandidate = def[i];
        }
    }

    return minCandidate;
}

public double distance(double[] point1 , double[] point2) {
    // Calculates and Returns Euclidean distance        
    return 0;
}
}

1 个答案:

答案 0 :(得分:1)

  • 确定并行任务应该执行的操作。最佳并行化是在交互最少的情况下。因此,计算xyz数组的一个元素是最佳候选。在10个块中拆分def很糟糕,因为这些块不是独立的。当我们想要增加任务的大小并因此减少任务的交互时,在一个线程中组合abc的10个元素可能有意义,但这是一个不明显的优化,应该在以后完成。

  • 决定如何运行这些任务。将每个任务包装在单独的Runnable中并提交到线程池是一种通用的方法,但在这里我们可以避免这种情况。每个大头钉都由索引标识为abc数组(和xyz数组)。我们可以将当前索引保存在AtomicInteger中,并使用getAndIncrement获取下一个索引。

  • 由于此任务受CPU约束,因此启动N个线程,其中N =可用处理器的数量。

  • 使用CountDownLatch计算已完成任务的数量。

在此处添加一些初始化和最小距离计算:

public class MinDistanceCalculation implements Runnable {  
    AtomicInteger idx=new AtomicInteger();
    int inpSize=100;
    double[] abc = new double[inpSize];
    double[] def = ...
    double[] xyz = new double[inpSize];
    CountDownLatch counter=new CountDownLatch(inpSize);

     public void run() {
      for (;;) {
       int nextIndex=idx.getAndIncrement();
       if (nextIndex>=inpSize) return;
       xyz[nextIndex]=minDistance(abc[nextIndex], def);
       counter.countDown();
    }

    void start() {
     for (int k=0; k<Runtime.getRuntime.availableProcessors()) {
        new Thread(this).start();
     }
     counter.await();
    }

    public static void main(String[] a) {
       new MinDistanceCalculation().start();
    }
  }