我一直致力于使用线程对矩阵进行倍增的程序。我以非线程方式编写程序,它的工作就像一个魅力。然而,当我用线程函数编写它时,似乎我没有从Threading类中获得结果(稍后我将重命名)。此外,如果我使用1个线程,我将获得所有3个矩阵,然后是matC矩阵的空结果。超过1的任何东西都会让我得到一个超出界限的数组索引。
使用类和诸如此类的东西仍然非常无能,而且我在提出有点罗嗦之前道歉。但任何帮助都会受到赞赏。
主要课程:
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");
}
}
这是我的线程类:
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];
}
}
}
}
}
以下是使用2行和1个线程的结果
Matrix 1: 7 8 4 5
Matrix 2: 3 0 1 5
结果: 0 0 0 0
答案 0 :(得分:3)
这里有很多问题。首先是这个循环:
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++;
}
在调用matrixFill
之前运行此循环。此时matA
和matB
都等于零矩阵。
然后,对于每个Thread
,请等待完成的join()
。所以你要做的只是0 * 0 = 0
N 2 次。
在循环中创建线程并在创建它们时调用join()
等待每个线程完成。这意味着您从不并行运行两个任务。这不是线程,这是以一种非常复杂的方式对单个线程做某事。
然后填写matA
和matB
并打印出所有三个。不出所料,matC
仍然等于零矩阵。
您的下一个问题是您的线程:
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];
}
}
}
}
每个线程都运行此代码。此代码将两个矩阵相乘。运行此代码N 2 次,就会使单个矩阵乘法N 2 变慢。
如果您修复了线程(见上文)以便所有线程同时运行,那么您所拥有的就是创建Java以来最大的竞争危险。我非常怀疑你会永远得到正确的结果。
TL; DR matC
为零的原因是,当乘法发生时,maA == matB == 0
。
答案 1 :(得分:0)
首先,我不知道你为什么用相同的数据运行线程N ^ 2次。您是否希望每次使用不同的数据填充matA和matB?
如果要并行计算多个数据,则应以这种方式进行:
//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();
}
否则没有什么是平行的,因为你等到第一个Thread准备就绪然后再做下一个。
你得到0 0 0 0的结果是因为你启动线程时matA和matB都是0 0 0 0。