如何显示班级的结果?

时间:2014-10-07 07:11:20

标签: java arrays class matrix-multiplication

我一直致力于使用线程对矩阵进行倍增的程序。我以非线程方式编写程序,它的工作就像一个魅力。然而,当我用线程函数编写它时,似乎我没有从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

2 个答案:

答案 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之前运行此循环。此时matAmatB都等于零矩阵。

然后,对于每个Thread,请等待完成的join()。所以你要做的只是0 * 0 = 0 N 2 次。

在循环中创建线程并在创建它们时调用join() 等待每个线程完成。这意味着您从不并行运行两个任务。这不是线程,这是以一种非常复杂的方式对单个线程做某事。

然后填写matAmatB并打印出所有三个。不出所料,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。