2016-02-05 97 views
-1

我有一个随机整数的2d矩阵。我想在每一行中找到最小值和最大值(每行由不同的线程完成),然后我想整理结果并在所有矩阵中找到最小值和最大值。这是主要的代码:线程对象如何访问关联对象的方法?

public static void main(String[] args) { 
    double maxGlob = 0.0;//max in all matrix 
    double minGlob = 1.0;//min in all matrix 

    makeData m = new makeData(); 
    Double[][] x = m.generateData(100, 200);//generate matrix 
    Thread[] t = new MinMaxFinder[100];//make hundred threads - MinMaxFinder extends Thread 

    for(int i = 0; i < 100; i++){ 
     t[i] = new MinMaxFinder(x[i], " and I'm thread: " + i); 
     t[i].start(); 

    }//end of for 

    try{ 

     for(int i = 0; i < 100; i++){ 
      t[i].join();//wait for thread i when finished 
      if(t[i].findMax() > maxGlob) //this is the problem, I can't access findMax which is in MinMaxFinder 
       maxGlob = t[i].findMax(); 
      if(t[i].findMin() < minGlob) //same with min 
       minGlob = t[i].findMin(); 
     } 
    }catch(InterruptedException e){} 
     //when done with all threads, print global max and min values for all matrix 
     System.out.println("Max is: " + maxGlob + " and min is: " + minGlob);  
}//end of main 
+0

这使我心情抑郁,这种非问题了upvote。 – Raedwald

回答

1

100个线程是疯狂为你想要做什么。我怀疑你可以证明使用一个线程来处理你创建一个线程的开销。让我们不要提到为100x200随机分配空间不是必须的。您可以简单地调用随机20k次并对这些值执行相同的计算。

但是,让我们假设这是一个学习练习。如果您想要并行执行计算,那么您需要随意细分网格,以便每个线程都有自己的部分而不重叠。然后为了在线程中使用它,你只需要将它传递给你的MinMaxFinder线程。

因此,像:

class MinMaxFinder extends Thread { 
    private int minRow, maxRow, minColumn, maxColumn; 
    private Double[][] grid; 

    public MinMaxFinder(Double[][] grid) { 
     this.grid = grid; 
    } 

    public void start(int minRow, int maxRow, int minColumn, int maxColumn) { 
     this.minRow = minRow; 
     this.maxRow = maxRow; 
     this.minColumn = minColumn; 
     this.maxColumn = maxColumn; 

     super.start(); 
    } 

    public void start() { 
     // perform search 
    } 
} 

没有什么神奇这里发生的一切。只要你没有写入网格,并且你没有重叠网格,就没有并发问题的风险。

我会建议用大量线程的处理,当你看看ThreadPoolExecutor。它有许多组织线程和潜在的重复使用它们,以及有用的方法。

1

如果你想收集并行线程的结果,我建议使用Future抽象。特别是我会在FutureTask实用程序的帮助下做到这一点。

public class RandomMatrixMinMax { 

    public static void main(String[] args) { 
     double maxGlob = 0.0;// max in all matrix 
     double minGlob = 1.0;// min in all matrix 

     final Double[][] x = generateData(100, 200);// generate matrix 
     final MinMaxFinderTask[] t = new MinMaxFinderTask[100];// make hundred 
                   // threads - 
     // MinMaxFinder extends Thread 

     for (int i = 0; i < 100; i++) { 
      t[i] = new MinMaxFinderTask(x[i]); 
      new Thread(t[i]).start(); 
     } // end of for 

     try { 

      for (int i = 0; i < 100; i++) { 
       if (t[i].get().getMax() > maxGlob) { 
        maxGlob = t[i].get().getMax(); 
       } 
       if (t[i].get().getMin() < minGlob) { 
        minGlob = t[i].get().getMin(); 
       } 
      } 

     } catch (final InterruptedException | ExecutionException e) { 
     } 
     // when done with all threads, print global max and min values for all 
     // matrix 
     System.out.println("Max is: " + maxGlob + " and min is: " + minGlob); 

    }// end of main 

    private static Double[][] generateData(int rows, int cols) { 
     final Double[][] randomMatrix = new Double[rows][cols]; 
     final Random random = new Random(); 
     for (int i = 0; i < cols; i++) { 
      for (int j = 0; j < rows; j++) { 
       randomMatrix[j][i] = random.nextDouble(); 
      } 
     } 
     return randomMatrix; 
    } 

    private static class MinMaxResult { 
     private Double min; 
     private Double max; 

     public MinMaxResult(Double min, Double max) { 
      this.min = min; 
      this.max = max; 
     } 

     public Double getMin() { 
      return min; 
     } 

     public void setMin(Double min) { 
      this.min = min; 
     } 

     public Double getMax() { 
      return max; 
     } 

     public void setMax(Double max) { 
      this.max = max; 
     } 
    } 

    private static class MinMaxFinderTask extends FutureTask<MinMaxResult> { 

     public MinMaxFinderTask(Double[] row) { 
      super(new MinMaxCalculator(row)); 
     } 

    } 

    private static class MinMaxCalculator implements Callable<MinMaxResult> { 

     private final Double[] row; 

     public MinMaxCalculator(Double[] row) { 
      this.row = row; 
     } 

     @Override 
     public MinMaxResult call() throws Exception { 
      Double min = row[0]; 
      Double max = row[0]; 
      for (int i = 1; i < row.length; i++) { 
       if (row[i] < min) { 
        min = row[i]; 
       } 
       if (row[i] > max) { 
        max = row[i]; 
       } 
      } 
      return new MinMaxResult(min, max); 
     } 
    } 

} 

无论如何,我同意尼尔,这100个简单任务的线程太多了。作为一种替代ThreadPoolExecutor可以委托计算的并行与Java引入了新的流API 8

在Java 8应用程序可以是:

public class RandomMatrixMinMax { 

    public static void main(String[] args) { 
     final Double[][] x = generateData(100, 200); 
     // obtain an array with min/max of each row of the matrix. The 
     // intermediate operation 'parallel' makes the computation parallel. 
     final MinMaxResult[] rowResults = Arrays.stream(x).parallel() 
       .map(row -> new MinMaxResult(Arrays.stream(row).min(Double::compare).get(), 
         Arrays.stream(row).max(Double::compare).get())) 
       .toArray(size -> new MinMaxResult[size]); 
     final Double maxGlob = Arrays.stream(rowResults).map(MinMaxResult::getMax).max(Double::compare).get(); 
     final Double minGlob = Arrays.stream(rowResults).map(MinMaxResult::getMin).min(Double::compare).get(); 
     System.out.println("Max is: " + maxGlob + " and min is: " + minGlob); 
    } 

    private static Double[][] generateData(int rows, int cols) { 
     final Double[][] randomMatrix = new Double[rows][cols]; 
     final Random random = new Random(); 
     for (int i = 0; i < cols; i++) { 
      for (int j = 0; j < rows; j++) { 
       randomMatrix[j][i] = random.nextDouble(); 
      } 
     } 
     return randomMatrix; 
    } 

    private static class MinMaxResult { 
     private Double min; 
     private Double max; 

     public MinMaxResult(Double min, Double max) { 
      this.min = min; 
      this.max = max; 
     } 

     public Double getMin() { 
      return min; 
     } 

     public void setMin(Double min) { 
      this.min = min; 
     } 

     public Double getMax() { 
      return max; 
     } 

     public void setMax(Double max) { 
      this.max = max; 
     } 
    } 
}