Reputation: 13
I've been working on a program which multiplies matrices using threads. I written the program in a non-threaded fashion and it was working like a charm. However when I was writing it w/ threading function, it appears that I am not getting a result from the Threading class (I will rename it later on). Also if I were to use 1 thread, I would get all 3 matrices followed by a empty results for the matC matrix. Anything more than 1 would get me a Array index out of bounds.
Still pretty inept using classes and whatnot, and i apologize in advance of being somewhat wordy. But any help would be appreciated.
Main class:
package matrixthread;
import java.io.*;
import java.util.*;
public class MatrixThread extends Thread{
public static void matrixPrint(int[][] A) {
int i, j;
for (i = 0; i < A.length; i++) {
for (j = 0; j < A.length; j++) {
System.out.print(A[i][j] + " ");
}
System.out.println("");
}
}
public static void matrixFill(int[][] A) {
int i, j;
Random r = new Random();
for (i = 0; i < A.length; i++) {
for (j = 0; j < A.length; j++) {
A[i][j] = r.nextInt(10);
}
}
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int threadCounter = 0;
System.out.print("Enter number of rows: ");
int M = in.nextInt();
System.out.print("Enter number of threads: ");
int N = in.nextInt();
Thread[] thrd = new Thread[N];
if (M < N)
{
System.out.println("Error! Numbers of rows are greater than number of threads!");
System.exit(0);
}
if(M % N != 0)
{
System.out.println("Error! Number of rows and threads aren't equal");
System.exit(0);
}
int[][] matA = new int[M][M];
int[][] matB = new int[M][M];
int[][] matC = new int[M][M];
try
{
for (int x = 0; x < N; x ++)
for (int y = 0; y < N; y++)
{
thrd[threadCounter] = new Thread(new Threading(matA, matB, matC));
thrd[threadCounter].start();
thrd[threadCounter].join();
threadCounter++;
}
}
catch(InterruptedException ie){}
long startTime = (int)System.currentTimeMillis();
matrixFill(matA);
matrixFill(matB);
//mulMatrix(matA, matB, matC);
long stopTime = (int)System.currentTimeMillis();
int execTimeMin = (int) ((((stopTime - startTime)/1000)/60)%60);
int execTimeSec = ((int) ((stopTime - startTime)/1000)%60);
System.out.println("\n" + "Matrix 1: ");
matrixPrint(matA);
System.out.println("\n" + "Matrix 2: ");
matrixPrint(matB);
System.out.println("\n" + "Results: ");
matrixPrint(matC);
System.out.println("\n" + "Finish: " + execTimeMin + "m " + execTimeSec + "s");
}
}
And here's my threading class:
package matrixthread;
public class Threading implements Runnable {
//private int N;
private int[][] matA;
private int[][] matB;
private int[][] matC;
public Threading(int matA[][], int matB[][], int matC[][]) {
this.matA = matA;
this.matB = matB;
this.matC = matC;
}
@Override
public void run() {
int i, j, k;
for (i = 0; i < matA.length; i++) {
for (j = 0; j < matA.length; j++) {
for (k = 0; k < matA.length; k++) {
matC[i][j] += matA[i][k] * matB[k][j];
}
}
}
}
}
Here are my results using 2 rows and 1 thread
Matrix 1: 7 8 4 5
Matrix 2: 3 0 1 5
Results: 0 0 0 0
Upvotes: 1
Views: 112
Reputation: 61168
You have a large number of problems here. First and foremost is this loop:
for (int x = 0; x < N; x ++)
for (int y = 0; y < N; y++) {
thrd[threadCounter] = new Thread(new Threading(matA, matB, matC));
thrd[threadCounter].start();
thrd[threadCounter].join();
threadCounter++;
}
You run this loop before calling matrixFill
. matA
and matB
are both equal to the Zero matrix at this point.
You then, for each Thread
, call join()
which waits for completion. So all you do is 0 * 0 = 0
N2 times.
Creating threads in a loop and calling join()
on them as they are created waits for each thread to finish. This means that you never have two tasks running in parallel. This isn't threading, this is doing something with a single thread in a very complicated manner.
You then fill matA
and matB
and print out all three. Unsurprisingly, matC
is still equal to the Zero matrix.
Your next issue is with your threading:
public void run() {
int i, j, k;
for (i = 0; i < matA.length; i++) {
for (j = 0; j < matA.length; j++) {
for (k = 0; k < matA.length; k++) {
matC[i][j] += matA[i][k] * matB[k][j];
}
}
}
}
Each thread runs this code. This code multiplies two matrices. Running this code N2 times as you do just makes a single matrix multiplication N2 times slower.
If you fixed your threading (see above) so that all your threads ran concurrently then all you would have is the biggest race hazard since in creation of Java. I highly doubt you would ever get the correct result.
TL;DR The reason matC
is zero is because, when multiplication happens, maA == matB == 0
.
Upvotes: 3
Reputation: 317
First of all I don't know why you run the thread with the same data N^2 times. Possible you wanted to fill matA and matB every time with different data?
If you want to compute many data parallel you should do it in this way:
//First start all Threads
for (int x = 0; x < N; x ++)
for (int y = 0; y < N; y++)
{
thrd[threadCounter] = new Thread(new Threading(matA, matB, matC));
thrd[threadCounter].start();
threadCounter++;
}
//then wait for all
for(int i = 0; i < threadCounter; i++){
thrd[threadCounter].join();
}
Otherwise there is nothing parallel because you wait until the first Thread is ready and then do the next.
That you get a result of 0 0 0 0 is because matA and matB are 0 0 0 0 at the moment you start the threads.
Upvotes: 0