2
votes

I have to create a program that simulates concurrent matrix addition and multiplication. I realize that if I have 3 matrices: A, B, and C, and I want to calculate A+B = C or A*B = C, then the maximum amount of threads I can create are (rows in C) * (columns in C), since each final position in matrix C can be calculated independent of the other positions.

My real question is this: if I have a interface MatrixMath which has methods multiply(), add(), print(), how can I ensure that when the add() or multiply() methods terminate, all the changes are done being written to the product or sum matrix?

Example:

class MatrixMathImplementation implements MatrixMath {

  public void multiply(int[][]A, int[][]B, int[][]C) {
    //multiply the two matrices, spawning m*n threads
    //haven't coded this yet
  }

  public void add(int[][]A, int[][]B, int[][]C) {
      //add the two matricies, spawning m*n threads
      //First: Check that A, B, and C are all the same size
      if (A.length == B.length && A.length == C.length &&
        A[0].length == B[0].length && A[0].length == C[0].length) {

        for (int row=0; row < A.length; row++) {
          for (int col=0; col < A[0].length; col++) {
              new MatrixSumThread(A,B,C,row,col);
          }
        }    
      } else {
        System.out.println("ERROR: Arrays are not the same size.");
      }
    }
  }

  public void print() {
    //print the given matrix
    //doesn't need to be concurrent, haven't coded this yet either.
  }
}

In the code, MatrixSumThread creates a runnable that will calculate the sum needed for the specific row and column, and put it into that row and column in matrix C. I'll make a similar runnable class for MatrixProductThread.

Any ideas on how to make sure that if I have:

someMatrixMathObject.add(A,B,C);
someMatrixMathObject.multiply(A,B,C);

That I can ensure the add finishes before the multiply, or vice versa? Thank you for any help.

1
Push the tasks into a Collection<Callable<Void>> and then chuck all those into ExecutorService.invokeAll - this will return when its done. P.S. do you really think it's worth using threads to add each pair of numbers? (hint; no, it's not).Boris the Spider
I would listen to @BoristheSpider, but if you want to handle everything yourself, then you should read this article about joining threads. "Let's say I need to spawn multiple threads to do the work, and continue to the next step only after all of them complete. ... The key point is to use Thread.join() method."atomman
@BoristheSpider thanks for the tip, I'll look into that! And realistically: no, I do not think it's worth using multiple threads. This is for a University assignment however in which the point is to maximize controlling different threads in this situation, not necessarily creating a realistic scenario.John Davidson
@atomman thanks for the tip! Article seems helpful.John Davidson
Doing a thread for each pair of values seems senseless, I can see how dividing the matrix in submatrixes for multiple threads to operate on would be sensible though.arynaq

1 Answers

2
votes

Generally speaking, here's how you work with raw threads:

Thread t = new Thread(); // or subclass thereof
t.start();  // make sure to not start threads in the constructor; start explicitly
t.join();   // waits for the thread to finish

in your case:

// create a list to hold all your threads, above the for loops
List<MatrixSumThread> threads = new ArrayList<MatrixSumThread>();
// for() { ...
// make sure MatrixSumThread doesn't call start() in its constructor
MatrixSumThread t = new MatrixSumThread(A,B,C,row,col);
threads.add(t);
t.start();

then later, after you're done with for-loops, join all the threads:

for (MatrixSumThread t in threads) {
  t.join();
}