0

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

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

我的问题是

  • 如何等待abc(ie defthreads) 的子线程。我已经通过了 java join 方法,但无法弄清楚如何使用它。

  • 在这种情况下我可以使用循环障碍吗?

  • 实际数据在 1000abc和 10000的数量级,def而且我之前没有使用过线程,所以这个实现是否会出现任何问题。另外,我在某些示例中看到了使用 of ThreadPoolExecutor而不是 the FixedThreads,但无法弄清楚ThreadPoolExecutor会有多少。

1.距离计算

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

}

子线程/定义线程

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

1 回答 1

1
  • 确定并行任务应该做什么。最好的并行化是交互最少的时候。因此,计算 xyz 数组的一个元素是最佳候选。将 def 分成 10 个块是不好的,因为这些块不是独立的。当我们想增加任务的大小从而减少任务的交互时,将 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();
    }
  }
于 2013-10-07T08:31:11.447 回答