一旦我向Runnable
提交ThreadExecutor
,它就会退出,我无法弄清楚原因。我已经跟踪了代码,但无济于事。有谁知道为什么会这样?
退出,我的意思是提交任务,它永远不会运行Multiplier
类(运行方法) - 第一次提交到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
答案 0 :(得分: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;
}
这将确保您在实际提取乘法结果之前等待线程完成。您的代码可能需要对此进行一些重构。
答案 1 :(得分: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;
}
将使用cols
,其值为20
。但是您的matrix
已创建为
matrix = new Double[rows][cols]; // 20 x 20
所以最后一个索引是19.这会抛出你吞下的ArrayIndexOutOfBoundsException
,你的应用程序以状态码0结束,因为方法正常返回。
将其更改为
columnsOfRow[i] = this.matrix[row][i];