2014-10-01 74 views
-2

只要我提交RunnableThreadExecutor,它就退出,我不知道爲什麼。我追溯了代碼,但無濟於事。有沒有人有任何想法,爲什麼會這樣?ThreadPool在提交時退出

通過退出,我的意思是任務提交,它永遠不會運行Multiplier類(run方法) - 第一個提交ThreadPool剛剛關閉,退出代碼0

public class Main { 
    public static void main(String[] args) { 

     /** 
     * 0: threads 
     * 1: matrix A 
     * 2: matrix B 
     * 3: matrix C -- output file 
     */ 
     Object[] parsedArgs = CommandLineArgParser.getArguments(args); // strip arguments -- contains help and exit upon incorrect entries 

     try { 
      // Create thread pool 
      int threads = Integer.parseInt((String) parsedArgs[0]); 
      ExecutorService threadPool; 
      if (threads > 0) { 
       threadPool = Executors.newFixedThreadPool(threads*2); // create twice as many threads as OS cores 
      }else 
      throw new InputMismatchException("Threads must be an Integer"); 

      // Create matrices: 
      Matrix m1 = getMatrix((String) parsedArgs[1]); 
      Matrix m2 = getMatrix((String) parsedArgs[2]); 
      Matrix m3 = null; 
      try { 
       m3 = m1.multiply(m2, threadPool); 
       } catch (ExecutionException exE) { 
       System.exit(1); 
       } catch (InterruptedException iE) { 
       System.exit(1); 
      } 
      threadPool.shutdown(); 

      try { 
       threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); 
       } catch (InterruptedException e) { 
       System.out.println("The operation is taking too long. Exiting."); 
       System.exit(1); 
      } 

      // Write to file! 
      m3.writeToFile((String)parsedArgs[3]); 

      }catch (ArrayIndexOutOfBoundsException arrayOutBounds) { 
      // means that correct arguments were not passed in. print them. 

     } 

    } 

    public static Matrix getMatrix(String filePath) { 
     try { 
      return MatrixCreator.createMatrix(filePath); 
      } catch (IOException ioE) { 
      // Matrix could not be found in filesystem 
      System.out.println("The matrix path (" + filePath +") supplied could not be found in the filesystem. If you have not already, try an absolute path."); 
      System.exit(0); //exit so that user may re-enter 
     } 
     return null; // should never happen 
    } 
} 

public class Matrix { 

    int rows, cols; // number of rows and columns in matrix, respectively. 
    Double [][] matrix; 

    public Matrix(int rows, int cols) { 
     this.rows = rows; 
     this.cols = cols; 
     matrix = new Double[rows][cols]; // create matrix of proper size 
    } 

    /** 
    * Inserts value into matrix 
    * @param row row in which to insert element 
    * @param col column in which to insert element 
    * @param val 
    */ 
    public void insertValue(int row, int col, double val) { 
     matrix[row][col] = val; // no error checking applied for column or row -- would reduce speed when inserting thousands of values 
    } 

    /** 
    * A is THIS matrix. <code>multiply()</code> computes AB = C. 
    * @param B matrix by which to multiply 
    * @param threadPool thread pool to use 
    * @return matrix C 
    */ 
    public Matrix multiply(Matrix B, ExecutorService threadPool) throws ExecutionException, InterruptedException { 
     System.out.println("In multiply.."); 
     Matrix C = new Matrix(this.rows, B.cols); // create matrix C of appropriate size 
     ArrayList<Future<?>> futures = new ArrayList<Future<?>>(); 
     for (int i = 0; i < C.rows; i++) { 
      System.out.println(C.rows); 
      for (int j = 0; j < C.cols; j++) { 
       System.out.println(C.cols); 
       System.out.println("Here"); 
       futures.add(threadPool.submit(new Multiplier(this.getColumnsOfRow(i), B.getRowsOfColumn(j), C, i, j))); 
      } 
     } 
     for (Future<?> f : futures) { 
      f.get(); 
     } 
     return C; 
    } 

    private Double[] getRowsOfColumn(int column) { 
     Double[] rowsOfColumn = new Double[rows]; 
     for (int i = 0; i < rows; i++) { 
      rowsOfColumn[i] = this.matrix[i][column]; 
     } 
     return rowsOfColumn; 
    } 

    private Double[] getColumnsOfRow(int row) { 
     Double[] columnsOfRow = new Double[cols]; 
     for (int i = 0; i < cols; i++) { 
      columnsOfRow[i] = this.matrix[row][cols]; 
     } 
     return columnsOfRow; 
    } 

    // make string... 
    public String toString() { 
     String s = ""; 
     for (int i = 0; i < rows; i++) { 
      for (int j = 0; j < cols; j++) { 
       s += matrix[i][j] + ", "; 
      } 
      s += "\n"; 
     } 
     return s; 
    } 

    // write file to path provided 
    public void writeToFile(String filePath) { 
     System.out.println("Saving to: " + filePath); 
     try { 
      BufferedWriter writer = new BufferedWriter(new FileWriter(filePath, false)); 
      for (int i = 0; i < rows; i++) { 
       for (int j = 0; j < cols; j++) { 
        if (j == cols - 1) { 
         writer.write("" + matrix[i][j] + "\n"); 
         } else { 
         writer.write("" + matrix[i][j] + ","); 
        } 
       } 
      } 
      writer.close(); 
      } catch (IOException ioE) { 
      System.out.println("Could not save file to specified location. Printing stacktrace:"); 
      ioE.printStackTrace(); 
      System.exit(1); 
     } 
     System.out.println("Matrix successfully written to file: " + filePath); 
    } 

    class Multiplier implements Runnable { 

     Double[] ARow, BCol; 
     Matrix C; 
     int insertRow, insertCol; 
     /** 
     * This will method will multiply the row of matrix A and the 
     * column of matrix B on a thread. The result will be put into 
     * matrix C at the specified locations. 
     * @param ARow the Row to be multiplied by the column of matrix B 
     * @param BCol the Column to be multiplied by the row of matrix A 
     * @param C the matrix which will hold the resultant of the two operations. 
     * @param insertRow the row of matrix C in which to insert the multiplication 
     * @param insertCol the column of matrix C in which to insert the multiplication 
     */ 
     public Multiplier(Double[] ARow, Double[] BCol, Matrix C, int insertRow, int insertCol) { 
      System.out.println("We are here!"); 
      this.ARow = ARow; 
      this.BCol = BCol; 
      this.C = C; 
      this.insertRow = insertRow; 
      this.insertCol = insertCol; 
     } 

     @Override 
     public void run() { 
      double sum = 0; 
      for (int i = 0; i < ARow.length; i++) { 
       sum += ARow[i]*BCol[i]; 
      } 
      C.insertValue(insertRow,insertCol,sum); 
     } 
    } 

命令行整個程序使用的參數-t 8 -m1 /Users/me/Desktop/Matrices/matrixA.mat -m2 /Users/me/Desktop/Matrices/matrixB.mat -o /Users/me/Desktop/Matrices/output.mat

+2

你說的_quits_是什麼意思? – 2014-10-01 02:57:59

+0

它不創建乘數類,程序退出之前退出 – user2243357 2014-10-01 03:00:06

+0

看起來像引發異常? – 2014-10-01 03:00:25

回答

0

您的程序不能只提交作業並終止。所以,一旦你提交了所有的工作,你就必須做到以下幾點:

Future<Void> result = threadPool.submit(new Multiplier(this.getColumnsOfRow(i), 
               B.getRowsOfColumn(j), C, i, j)); 
result.get() 

這將確保您的代碼等待線程終止主線程之前完成。

此外,你可以看看CompletionService。例如,請參閱this

[根據編輯]

public Matrix multiply(Matrix B, ExecutorService threadPool) { 
    System.out.println("In multiply.."); 
    Matrix C = new Matrix(this.rows, B.cols); // create matrix C of appropriate size 
    ArrayList<Future<?>> futures = new ArrayList<Future<?>>(); 
    for (int i = 0; i < C.rows; i++) { 
     System.out.println(C.rows); 
     for (int j = 0; j < C.cols; j++) { 
      System.out.println(C.cols); 
      System.out.println("Here"); 
      futures.add(threadPool.submit(new Multiplier(this.getColumnsOfRow(i), B.getRowsOfColumn(j), C, i, j))); 
     } 
    } 
    for(Future<?> future: futures) { 
     future.get() 
    } 
    return C; 
} 

這將確保你在等待的線程來完成的,你居然拉相乘的結果之前。你的代碼可能需要對此進行一些重構。

+0

爲什麼在他們當前的設置中這些都是必需的? – 2014-10-01 03:16:10

+0

我假設這是用於瞭解Java併發程序包的虛擬代碼,而不是代碼審查。 – Aritra 2014-10-01 03:18:22

+0

這是我正在編寫的代碼,但這不起作用。 __只要將任務提交給ExecutorService,程序就會退出。我已發佈所有適用的代碼。 – user2243357 2014-10-01 03:19:59

0

你的代碼在這裏

private Double[] getColumnsOfRow(int row) { 
    Double[] columnsOfRow = new Double[cols]; 
    for (int i = 0; i < cols; i++) { 
     columnsOfRow[i] = this.matrix[row][cols]; 
    } 
    return columnsOfRow; 
} 

將使用cols20值。但是,你的matrix創建爲

matrix = new Double[rows][cols]; // 20 x 20 

所以最後指數是19.這將引發你吞下ArrayIndexOutOfBoundsException和方法正常返回你的應用程序,狀態碼0結束。

將其更改爲

columnsOfRow[i] = this.matrix[row][i]; 
+0

Sotirios,謝謝。對不起,浪費你的時間。愚蠢的錯誤。 – user2243357 2014-10-01 04:14:24

+0

@ user2243357如果您現在刪除了您的接受,則可以刪除您的問題。這些事情發生。你應該(幾乎)不會吞下異常,至少不會記錄它們。 – 2014-10-01 04:16:17

+0

謝謝你的建議!我不會在將來! – user2243357 2014-10-01 04:22:35