2016-02-05 124 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; 
     } 
    } 
}