Java ThreadPool在提交时退出

Java ThreadPool在提交时退出,java,multithreading,java.util.concurrent,Java,Multithreading,Java.util.concurrent,一旦我向ThreadExecutor提交Runnable,它就会退出,我不知道为什么。我查过密码,但没用。有人知道为什么会这样吗 通过退出,我的意思是任务被提交,它从不运行乘法器类的run方法-第一次提交到线程池只是关闭整个程序,退出代码为0 public class Main { public static void main(String[] args) { /** * 0: threads * 1: matrix A

一旦我向ThreadExecutor提交Runnable,它就会退出,我不知道为什么。我查过密码,但没用。有人知道为什么会这样吗

通过退出,我的意思是任务被提交,它从不运行乘法器类的run方法-第一次提交到线程池只是关闭整个程序,退出代码为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);
        }
    }

使用的命令行参数-t8-m1/Users/me/Desktop/matrixes/matrixA.mat-m2/Users/me/Desktop/matrixes/matrixB.mat-o/Users/me/Desktop/matrixes/output.mat您的程序不能只提交作业并终止。因此,提交所有作业后,您必须执行以下操作:

Future<Void> result = threadPool.submit(new Multiplier(this.getColumnsOfRow(i), 
                                                B.getRowsOfColumn(j), C, i, j));
result.get()
这将确保代码在终止主线程之前等待线程完成

此外,您还可以查看CompletionService。例如,见

[基于编辑]

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;
}
这将确保在实际提取乘法结果之前,您正在等待线程完成。为此,您的代码可能需要进行一些重构。

此处是您的代码

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;
}
最后一个指数是19。这会抛出一个ArrayIndexOutOfBoundsException,当方法正常返回时,您会接受该异常,并且应用程序以状态代码0结束

换成

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

“退出”是什么意思?它不会创建乘法器类,程序会在出现异常之前退出?我没有发现任何异常,您需要向我们展示更多。就目前情况而言,您所展示的任何内容都不能导致您所描述的内容。为什么在他们当前的设置中需要这些内容?我假设这是学习Java并发包的虚拟代码,而不是代码审查。这是我正在编写的伪代码,但这不起作用。一旦任务提交给ExecutorService,程序就会退出。我已经发布了所有适用的代码。问题是,如果您不执行get,您将不知道是否有任何线程因异常而终止,或者它们是否正常终止。因此,最好改用可调用线程,并从可调用线程的返回中获取线程的成功。可能不允许同时修改Matrix类,这是您对Matrix C所做的操作,并且所有线程都会立即终止并出现错误。由于您的Runnable没有打印任何日志,因此在您通过遍历期货来单独收集线程的状态之前,无法知道。我没有任何期货来遍历OTIRIOS,谢谢。对不起,浪费了你的时间。愚蠢的错误。@user2243357如果您现在删除accept,您可以删除您的问题。这些事情经常发生。您几乎不应该在不记录异常的情况下接受异常。
columnsOfRow[i] = this.matrix[row][i];