다음 코드는 행렬 목록을 곱합니다. 목록을 두 개의 목록으로 나누고 각 목록의 출력 행렬을 새 스레드에서 재귀 적으로 계산하는 함수가 있습니다. 함수가 하나의 행렬 만 포함하는 목록에 도달하면 행렬을 반환하고, 그렇지 않으면 앞의 두 목록의 두 출력 행렬 (첫 번째 행렬에 k 행이 있음)을 가져와 각각 k 행을 생성하고 각 행을 계산합니다. 출력.Java 실행시 한 번에 하나의 스레드가 실행됩니다.
import java.util.Scanner;
public class Q3_thread
{
public static void main(String[] args)
{
// input
// Note: input matrices are presumed correct and in order
Scanner scanner = new Scanner(System.in);
int count = scanner.nextInt();
scanner.nextLine();
Matrix[] matrices = new Matrix[count];
for (int i = 0; i < matrices.length; i++)
{
String string = scanner.nextLine().trim();
String[] dimensions = string.split("\\*");
int m = Integer.valueOf(dimensions[0]), n = Integer.valueOf(dimensions[1]);
matrices[i] = new Matrix(m, n);
for (int j = 0; j < m; j++)
{
for (int k = 0; k < n; k++)
{
matrices[i].a[j][k] = scanner.nextInt();
}
scanner.nextLine();
}
}
scanner.close();
// log
// System.out.println('---');
// for (int i = 0; i < matrices.length; i++)
// {
// System.out.print(matrices[i]);
// }
// output
MatricesRunnable mainRunnable = new MatricesRunnable(matrices, 0, matrices.length);
Thread mainThread = new Thread(mainRunnable);
mainThread.start();
try
{
mainThread.join();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.print(mainRunnable.output);
}
}
class Matrix
{
public int m, n;
public int[][] a;
public Matrix(int m, int n)
{
this.m = m;
this.n = n;
this.a = new int[m][n];
}
public static Matrix multiply(Matrix left, Matrix right)
{
Matrix output = new Matrix(left.m, right.n);
RowRunnable[] rowRunnables = new RowRunnable[left.m];
Thread[] threads = new Thread[left.m];
for (int i = 0; i < threads.length; i++)
{
rowRunnables[i] = new RowRunnable(left, right, i);
threads[i] = new Thread(rowRunnables[i]);
threads[i].start();
}
for (int i = 0; i < threads.length; i++)
{
try
{
threads[i].join();
output.a[i] = rowRunnables[i].output;
}
catch (InterruptedException e)
{
e.printStackTrace(System.err);
}
}
return output;
}
@Override
public String toString()
{
String output = "";
for (int i = 0; i < this.m; i++)
{
for (int j = 0; j < this.n; j++)
{
output += this.a[i][j] + " ";
}
output += "\n";
}
return output;
}
}
class MatricesRunnable implements Runnable
{
public Matrix[] matrices;
public int startIndex, endIndex; // [,)
public Matrix output;
public MatricesRunnable(Matrix[] matrices, int startIndex, int endIndex)
{
this.matrices = matrices;
this.startIndex = startIndex;
this.endIndex = endIndex;
}
@Override
public void run()
{
if (this.endIndex - this.startIndex == 0)
{
output = null;
}
else if (this.endIndex - this.startIndex == 1)
{
output = matrices[this.startIndex];
}
else if (this.endIndex - this.startIndex == 2)
{
output = Matrix.multiply(matrices[this.startIndex], matrices[this.startIndex + 1]);
}
else
{
int halfIndex = (endIndex + startIndex)/2; // int division
if ((this.endIndex - this.startIndex) % 2 == 1) // so that the longer sublist is at left
{
halfIndex++;
}
MatricesRunnable leftMatrixRunnable = new MatricesRunnable(matrices, startIndex, halfIndex);
Thread leftMatrixThread = new Thread(leftMatrixRunnable);
leftMatrixThread.start();
MatricesRunnable rightMatrixRunnable = new MatricesRunnable(matrices, halfIndex, endIndex);
Thread rightMatrixThread = new Thread(rightMatrixRunnable);
rightMatrixThread.start();
try
{
leftMatrixThread.join();
rightMatrixThread.join();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
output = Matrix.multiply(leftMatrixRunnable.output, rightMatrixRunnable.output);
}
}
}
class RowRunnable implements Runnable
{
public Matrix left, right;
public int index; // which row
public int[] output; // index-th row of output
public RowRunnable(Matrix left, Matrix right, int index)
{
this.left = left;
this.right = right;
this.index = index;
this.output = new int[this.right.n];
}
@Override
public void run()
{
for (int i = 0; i < this.right.n; i++)
{
int sum = 0;
for (int j = 0; j < this.left.n; j++)
{
sum += left.a[index][j] * right.a[j][i];
}
this.output[i] = sum;
}
}
}
문제가 단지 하나 개의 실행중인 스레드가, 결과적으로 그것으로 동일한 시간이 걸리는, 코드가 동시에 여러 스레드를 실행해야하지만 스레드를 확인할 때 (htop 명령을 사용)이며 스레드를 전혀 사용하지 않을 때와 마찬가지로 결과를 생성합니다. 왜 그런 경우입니까?
는 당신을 testcases를 생성하기 위해 다음 코드를 사용할 수 있습니다
#include <iostream>
#include <cstdlib>
using namespace std;
int main(int argc, char *argv[])
{
srand(atoi(argv[1]));
int n = atoi(argv[2]);
int maxRC = atoi(argv[3]);
int maxNum = atoi(argv[4]);
cout << n << endl;
int r = rand() % maxRC + 1;
for(int i = 0; i < n; i++)
{
int c = rand() % maxRC + 1;
cout << r << '*' << c << endl;
for(int j = 0; j < r; j++)
{
for(int k = 0; k < c; k++)
{
cout << rand() % (maxNum + 1) << ' ';
}
cout << endl;
}
r = c;
}
return 0;
}
인수는 각각 다음과 같습니다 행렬에서 임의 씨, 행렬의 수, 행과 열의 최대 길이, 숫자의 최대
스레드가 하나 뿐이며 mainThread이기 때문에 여러 스레드를 만들어야합니다. – Lrrr
실제로 여러 개의 기존 스레드가 실행 중이며 하나만 실행 중이거나 스레드가 전혀 생성되지 않았습니까? – chrylis
@Ali Amiri 네,하지만 mainThread는 두 개의 스레드를 만들고 두 스레드는 각각 두 개 더 만듭니다. 더 자세히 질문을 읽어보십시오. – Arianbakh