public class MatrixMultiply { public static double[][] multiply (double[][] a, double[][] b) { if (a.length != b[0].length || b.length != a[0].length) { throw new IllegalArgumentException("Mismatched arrays"); } // really need to check individual columns since arrays can be ragged???? double[][] c = new double[a.length][b[0].length]; Thread[] threads = new Thread[a.length*b[0].length]; int t = 0; // Einstein summation convention; see // http://mathworld.wolfram.com/MatrixMultiplication.html for (int i = 0; i < c.length; i++) { for (int k = 0; k < c[0].length; k++) { RowColumn rc = new RowColumn(i, k, a, b, c); Thread tr = new Thread(rc); tr.start(); threads[t++] = tr; } } // Likely need to improve this next bit for (int i = 0; i < threads.length; i++) { try { threads[i].join(); } catch (InterruptedException ex) { ex.printStackTrace(); } } return c; } } // No synchronization issues because the input arrays are read-only and // each thread writes to a different location. // This feels too granular. I should probably limit myself to one thread per row. class RowColumn implements Runnable { private int row; private int column; private double[][] a; private double[][] b; private double[][] c; // The real issue here is that we can;t pass arguments to run RowColumn(int row, int column, double[][] a, double[][] b, double[][] c) { this.row = row; this.column = column; this.a = a; this.b = b; this.c = c; } public void run() { for (int j = 0; j < b.length; j++) { c[row][column] += a[row][j]*b[j][column]; } } }