Java 用于乘法矩阵的同步线程
我整晚都在研究这个问题,还没有找到解决办法,所以如果有人能帮助我,我将非常感激!我可能错过了一些非常明显的东西。这是一个理解同步的赋值,我们在前面的赋值中使用线程乘以2个矩阵。在上一次分配中,每个线程乘以一行,因此线程数与行数相同 在这个任务中,我们只需要使用5个线程,所有线程都应该从一行/列开始,一旦线程完成,它就应该使用同步选择下一个可用的行/列,所以现在两个线程将完成相同的列 帮助我朝着正确的方向前进,但我肯定是在实施过程中出了问题,因为到目前为止,我只让程序实现了以下两个方面:Java 用于乘法矩阵的同步线程,java,multithreading,synchronization,matrix-multiplication,Java,Multithreading,Synchronization,Matrix Multiplication,我整晚都在研究这个问题,还没有找到解决办法,所以如果有人能帮助我,我将非常感激!我可能错过了一些非常明显的东西。这是一个理解同步的赋值,我们在前面的赋值中使用线程乘以2个矩阵。在上一次分配中,每个线程乘以一行,因此线程数与行数相同 在这个任务中,我们只需要使用5个线程,所有线程都应该从一行/列开始,一旦线程完成,它就应该使用同步选择下一个可用的行/列,所以现在两个线程将完成相同的列 帮助我朝着正确的方向前进,但我肯定是在实施过程中出了问题,因为到目前为止,我只让程序实现了以下两个方面: 5个线程
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Random;
import java.util.Scanner;
import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.Lock;
public class MatrixMult {
public static void main(String[] args){
int[][] matrixA;
int[][] matrixB;
int colA = 0;
int rowA = 0;
int colB = 0;
int rowB = 0;
Scanner userInput = new Scanner( System.in );
System.out.println("Please enter the dimensions of matrix A");
do{
System.out.print("column for matrix A: ");
colA = userInput.nextInt();
System.out.println();
} while(!validDimension(colA));
rowB = colA;
do{
System.out.print("row for matrix A: ");
rowA = userInput.nextInt();
System.out.println();
} while(!validDimension(rowA));
matrixA = new int[rowA][colA];
System.out.println("Please enter the dimensions of matrix B:");
do{
System.out.print("column for matrix B: ");
colB = userInput.nextInt();
System.out.println();
} while(!validDimension(colB));
matrixB = new int[rowB][colB];
fillMatrix(matrixA);
fillMatrix(matrixB);
System.out.println("Would you like to print out matrix A and B? (y/n)");
String userResponse = userInput.next();
if(userResponse.equalsIgnoreCase("y")){
System.out.println("Matrix A:");
printBackMatrix(matrixA);
System.out.println();
System.out.println("Matrix B:");
printBackMatrix(matrixB);
System.out.println();
}
int[][] matrixProduct3 = multMatrixWithThreadsSync(matrixA, matrixB);
String fileName = "C:/matrix.txt";
System.out.println("Matrix product is being written to "+fileName);
try {
printMatrixToFile(matrixProduct3, fileName);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static int[][] multMatrixWithThreadsSync(int[][] matrixA, int[][] matrixB) {
int[][] matrixProduct = new int[matrixA.length][matrixB[0].length];
int[] matrixProductColumn = new int[matrixA.length];
Runnable task = new MultMatrixByRow(matrixA, matrixB, matrixProduct);
for(int i=0; i<5; i++){
Thread worker = new Thread(task);
worker.start();
// System.out.println(worker.getName());
try {
worker.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return matrixProduct;
}
private static void printMatrixToFile(int[][] matrix, String fileName) throws IOException{
PrintWriter userOutput = new PrintWriter(new FileWriter(fileName));
for(int i=0; i<matrix.length; i++){
for(int j=0; j<matrix[0].length; j++){
userOutput.print(matrix[i][j]+" ");
}
userOutput.println();
}
userOutput.close();
}
private static void printBackMatrix(int[][] matrix) {
for(int i=0; i<matrix.length; i++){
for(int j=0; j<matrix[0].length; j++){
System.out.print(matrix[i][j]+" ");
}
System.out.println();
}
}
private static void fillMatrix(int[][] matrix) {
Random rand = new Random();
for(int i=0; i<matrix.length; i++){
for(int j=0; j<matrix[0].length; j++){
matrix[i][j] = rand.nextInt(100) + 1;
}
}
}
public static boolean validDimension(int dim){
if (dim <= 0 || dim >1000){
System.err.println("Dimension value entered is not valid");
return false;
}
return true;
}
}
导入java.io.FileWriter;
导入java.io.IOException;
导入java.io.PrintWriter;
导入java.util.Random;
导入java.util.Scanner;
导入java.util.concurrent.Semaphore;
导入java.util.concurrent.locks.Lock;
公共类矩阵结果{
公共静态void main(字符串[]args){
int[][]矩阵;
int[][]矩阵b;
int=0;
int-rowA=0;
int colB=0;
int-rowB=0;
扫描仪用户输入=新扫描仪(System.in);
System.out.println(“请输入矩阵A的尺寸”);
做{
系统输出打印(“矩阵A列:”;
colA=userInput.nextInt();
System.out.println();
}而(!validDimension(colA));
rowB=可乐;
做{
系统输出打印(“矩阵A的行:”;
rowA=userInput.nextInt();
System.out.println();
}而(!有效尺寸(rowA));
matrixA=新整数[rowA][colA];
System.out.println(“请输入矩阵B的尺寸:”);
做{
系统输出打印(“矩阵B列:”);
colB=userInput.nextInt();
System.out.println();
}而(!有效尺寸(colB));
matrixB=新整数[rowB][colB];
填充矩阵(matrixA);
填充矩阵(matrixB);
System.out.println(“是否要打印矩阵A和B?(y/n)”);
字符串userResponse=userInput.next();
if(userResponse.equalsIgnoreCase(“y”)){
System.out.println(“矩阵A:”);
打印返回矩阵(矩阵);
System.out.println();
System.out.println(“矩阵B:”);
打印返回矩阵(matrixB);
System.out.println();
}
int[][]matrixProduct3=带线程同步的多矩阵(matrixA,matrixB);
字符串fileName=“C:/matrix.txt”;
System.out.println(“矩阵产品正在写入”+文件名);
试一试{
printMatrixToFile(matrixProduct3,文件名);
}捕获(IOE异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
}
私有静态int[]multmatrix with threadsSync(int[]matrixA,int[]matrixB){
int[]matrixProduct=new int[matrixA.length][matrixB[0.length];
int[]matrixProductColumn=新int[matrixA.length];
可运行任务=新的多矩阵xByRow(matrixA、matrixB、matrixProduct);
对于(int i=0;i
您不是在ressource上同步,您需要共享一个锁对象(在静态上下文中或通过构造函数)
当你甚至不让它们同步工作时,我真的无法弄清楚你的程序中应该同步什么…你启动一个线程,直接等待它停止。
我认为您必须首先启动所有线程,然后在另一个循环中调用每个线程上的连接
另外,我不太确定你的线程应该分别解决什么问题,我认为它们都解决了整个产品矩阵。你需要共享一个变量,用于标识你访问的已处理行
我可以修复您的代码,但我希望您自己完成这项工作,因为理解线程并发性是一项任务
编辑:同步的解释:
Synchronized将对象作为锁,只有一个线程可以为其保存监视器。当监视器用于锁时,线程可以处理块,如果没有,他必须等待获取监视器。
在您的情况下,可以使用私有静态最终对象锁=新对象();
作为锁,您将在上同步
编辑2:我完全构建了您的代码
我对你完成所有的工作并不感到骄傲,但没关系,就在这里
package anything.synchronize_stackoverflow_post;
/**
* @date 21.11.2012
* @author Thomas Jahoda
*/
public class ConcurrentMatrixMultiplyingTask implements Runnable {
private int[][] matrixA;
private int[][] matrixB;
private int[][] matrixProduct;
//
private final ConcurrencyContext context;
public ConcurrentMatrixMultiplyingTask(ConcurrencyContext context, int[][] A, int[][] B, int[][] C) {
if (context == null) {
throw new IllegalArgumentException("context can not be null");
}
this.context = context;
this.matrixA = A;
this.matrixB = B;
this.matrixProduct = C;
}
@Override
public void run() {
while (true) {
int row;
synchronized (context) {
if (context.isFullyProcessed()) {
break;
}
row = context.nextRowNum();
}
System.out.println(Thread.currentThread().getName() + " is going to process row " + row);
// i'm not really sure if this matrix algorithm here is right, idk..
for (int j = 0; j < matrixB[0].length; j++) {
for (int k = 0; k < matrixA[0].length; k++) {
matrixProduct[row][j] += matrixA[row][k] * matrixB[k][j];
}
}
}
}
public static class ConcurrencyContext {
private final int rowCount;
private int nextRow = 0;
public ConcurrencyContext(int rowCount) {
this.rowCount = rowCount;
}
public synchronized int nextRowNum() {
if (isFullyProcessed()) {
throw new IllegalStateException("Already fully processed");
}
return nextRow++;
}
public synchronized boolean isFullyProcessed() {
return nextRow == rowCount;
}
}
}
package anything.synchronize\u stackoverflow\u post;
/**
*@date 21.11.2012
*@作者托马斯·贾霍达
*/
公共类ConcurrentMatrixMultiplyingTask实现Runnable{
私有int[][]矩阵;
私有int[][]矩阵b;
私有int[][]矩阵产品;
//
私有最终并发上下文;
公共ConcurrentMatrixMultiplyingTask(ConcurrentyContext上下文,int[]A,int[]B,int[]C){
if(上下文==null){
抛出新的IllegalArgumentException(“上下文不能为null”);
}
this.context=上下文;
这个矩阵=A;
这个矩阵xb=B;
this.matrixProduct=C;
}
@凌驾
公开募捐{
while(true){
int行;
已同步(上下文){
if(context.isFullyProcessed()){
打破
}
row=context.nextRowNum();
}
System.out.println(Thread.currentThread().getName()+“将处理行”+行);
//我不确定这里的矩阵算法是否正确,idk。。
对于(int j=0;jpackage anything.synchronize_stackoverflow_post;
/**
* @date 21.11.2012
* @author Thomas Jahoda
*/
public class ConcurrentMatrixMultiplyingTask implements Runnable {
private int[][] matrixA;
private int[][] matrixB;
private int[][] matrixProduct;
//
private final ConcurrencyContext context;
public ConcurrentMatrixMultiplyingTask(ConcurrencyContext context, int[][] A, int[][] B, int[][] C) {
if (context == null) {
throw new IllegalArgumentException("context can not be null");
}
this.context = context;
this.matrixA = A;
this.matrixB = B;
this.matrixProduct = C;
}
@Override
public void run() {
while (true) {
int row;
synchronized (context) {
if (context.isFullyProcessed()) {
break;
}
row = context.nextRowNum();
}
System.out.println(Thread.currentThread().getName() + " is going to process row " + row);
// i'm not really sure if this matrix algorithm here is right, idk..
for (int j = 0; j < matrixB[0].length; j++) {
for (int k = 0; k < matrixA[0].length; k++) {
matrixProduct[row][j] += matrixA[row][k] * matrixB[k][j];
}
}
}
}
public static class ConcurrencyContext {
private final int rowCount;
private int nextRow = 0;
public ConcurrencyContext(int rowCount) {
this.rowCount = rowCount;
}
public synchronized int nextRowNum() {
if (isFullyProcessed()) {
throw new IllegalStateException("Already fully processed");
}
return nextRow++;
}
public synchronized boolean isFullyProcessed() {
return nextRow == rowCount;
}
}
}
package anything.synchronize_stackoverflow_post;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Random;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* @date 21.11.2012
* @author Thomas Jahoda
*/
public class MatrixMulti {
public static void main(String[] args) {
int[][] matrixA;
int[][] matrixB;
int colA = 0;
int rowA = 0;
int colB = 0;
int rowB = 0;
Scanner userInput = new Scanner(System.in);
System.out.println("Please enter the dimensions of matrix A");
do {
System.out.print("column for matrix A: ");
colA = userInput.nextInt();
System.out.println();
} while (!validDimension(colA));
rowB = colA;
do {
System.out.print("row for matrix A: ");
rowA = userInput.nextInt();
System.out.println();
} while (!validDimension(rowA));
matrixA = new int[rowA][colA];
System.out.println("Please enter the dimensions of matrix B:");
do {
System.out.print("column for matrix B: ");
colB = userInput.nextInt();
System.out.println();
} while (!validDimension(colB));
matrixB = new int[rowB][colB];
fillMatrix(matrixA);
fillMatrix(matrixB);
System.out.println("Would you like to print out matrix A and B? (y/n)");
String userResponse = userInput.next();
if (userResponse.equalsIgnoreCase("y")) {
System.out.println("Matrix A:");
printBackMatrix(matrixA);
System.out.println();
System.out.println("Matrix B:");
printBackMatrix(matrixB);
System.out.println();
}
int[][] matrixProduct3 = multMatrixWithThreadsSync(matrixA, matrixB);
String fileName = "test.txt";
System.out.println("Matrix product is being written to " + fileName);
try {
printMatrixToFile(matrixProduct3, fileName);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static int[][] multMatrixWithThreadsSync(int[][] matrixA, int[][] matrixB) {
int[][] matrixProduct = new int[matrixA.length][matrixB[0].length];
int[] matrixProductColumn = new int[matrixA.length];
//
ConcurrentMatrixMultiplyingTask.ConcurrencyContext context = new ConcurrentMatrixMultiplyingTask.ConcurrencyContext(matrixProduct.length);
//
Runnable task = new ConcurrentMatrixMultiplyingTask(context, matrixA, matrixB, matrixProduct);
Thread[] workers = new Thread[5];
for (int i = 0; i < workers.length; i++) {
workers[i] = new Thread(task, "Worker-"+i);
}
for (int i = 0; i < workers.length; i++) {
Thread worker = workers[i];
worker.start();
}
for (int i = 0; i < workers.length; i++) {
Thread worker = workers[i];
try {
worker.join();
} catch (InterruptedException ex) {
Logger.getLogger(MatrixMulti.class.getName()).log(Level.SEVERE, null, ex);
}
}
return matrixProduct;
}
private static void printMatrixToFile(int[][] matrix, String fileName) throws IOException {
PrintWriter userOutput = new PrintWriter(new FileWriter(fileName));
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length; j++) {
userOutput.print(matrix[i][j] + " ");
}
userOutput.println();
}
userOutput.close();
}
private static void printBackMatrix(int[][] matrix) {
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length; j++) {
System.out.print(matrix[i][j] + " ");
}
System.out.println();
}
}
private static void fillMatrix(int[][] matrix) {
Random rand = new Random();
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length; j++) {
matrix[i][j] = rand.nextInt(100) + 1;
}
}
}
public static boolean validDimension(int dim) {
if (dim <= 0 || dim > 1000) {
System.err.println("Dimension value entered is not valid");
return false;
}
return true;
}
}
class Cell; // int x, int y, getters, setters, ...
// build the structure that contains the work to be shared
List<Cell> cells = new LinkedList<Cell>();
for (int i=0;i<a.rows;i++) {
for (int j=0;j<b.columns;j++) {
cells.add(new Cell(i,j)); // represent the cells of my result matrix
}
}
class DotProduct implements Runnable {
int[][] a;
int[][] b;
int[][] result;
List<Cell> cells;
public DotProduct(int[][] a, int[][] b, int[][]result, List<Cell> cells) {
...
}
public void run() {
while(true) {
Cell cell = null;
synchronized(cells) { // here, we ensure exclusive access to the shared mutable structure
if (cells.isEmpty()) return; // when there're no more cells, we are done.
Cell cell = cells.get(0); // get the first cell not calculated yet
cells.remove(cell); // remove it, so nobody else will work on it
}
int x = cell.getX();
int y = cell.getY();
z = a.row(x) (dot) b.column(y);
synchronized (result) {
result[x][y] = z;
}
}
}