gpt4 book ai didi

java - Java中的多线程矩阵乘法

转载 作者:搜寻专家 更新时间:2023-11-01 03:46:43 24 4
gpt4 key购买 nike

我正在尝试构建一个程序,使用 a*d 线程(将用于在完成的文件中打印一个索引的总和)来将两个矩阵 (A[a,b], B[c,d]) 相乘矩阵),为此,我使用了一个“监视器”类,它将用作线程之间同步的 Controller ,“乘数”类代表单个线程和一个主程序类。我的想法是线程将进行计算,当 thread(0,0) 打印他的总和时,他将发出下一个信号。由于某种原因,在打印第一个索引后 - 所有线程都处于等待模式,不会测试我的条件。你能看看我的代码并告诉我我的错误在哪里吗?

监控类:

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

final class Monitor {
private Lock lock;
int index;
Condition cond;
public Monitor () {
lock = new ReentrantLock();
cond = lock.newCondition();
this.index = 0;
}

public synchronized void finished(int x, double sum) throws InterruptedException {
lock.lock();
if(index != x) {
while(index != x) cond.await();
System.out.printf("%9.2f ",sum);
index++;
lock.unlock();
cond.signalAll();
}
else {
System.out.printf("%9.2f ",sum);
index++;
try { lock.unlock(); }
catch (java.lang.IllegalMonitorStateException e) {};
try { lock.unlock(); }
catch (java.lang.IllegalMonitorStateException e) {};
}
if(index % 5 == 0) System.out.println();
}
}

乘数:

public class Multiplier extends Thread {
private int index;
private double [] vectorOne;
private double [] vectorTwo;
private Monitor monitor;
private double sum;

//constructor
public Multiplier(int index, Monitor monitor,double [] vectorOne,double [] vectorTwo) {
this.index = index;
this.monitor = monitor;
this.vectorOne = vectorOne;
this.vectorTwo = vectorTwo;
}

public void VecMulti() {
sum = 0;
for (int i = 0 ; i < vectorOne.length ; i++)
sum += vectorOne[i] * vectorTwo[i];
}

public double getSum() {
return sum;
}

public void run() {
VecMulti();
try {
monitor.finished(index, sum);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

主类:

public class MatrixMultiTest {
public static void main(String[] args) {
Monitor monitor = new Monitor(3*5);
Matrix A = Matrix.random(3,4);
Matrix B = Matrix.random(4,5);
System.out.println("Matrix No1");
A.show();
System.out.println();
System.out.println("Matrix No2");
B.show();
System.out.println();
System.out.println("Multi Matrix");

for (int i = 0; i < 3; i++)
for (int j = 0; j < 5; j++) {
Multiplier myThr = new Multiplier(i*5+j,
monitor,A.getRow(i),B.getCol(j));
myThr.start();
try {
myThr.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

最佳答案

finished() 方法充满了问题:

  • 第一个问题是synchronized关键字。它必须被删除。使用此关键字,如果第一个进入的线程具有非零索引,则程序将死锁 - 线程将永远停放,等待条件发出信号,而信号永远不会到来,因为没有其他线程可以进入 finished () 方法。

  • 第二个错误在于 else block :

else {
System.out.printf("%9.2f ",sum);
index++;
try { lock.unlock(); }
catch (java.lang.IllegalMonitorStateException e) {};
try { lock.unlock(); }
catch (java.lang.IllegalMonitorStateException e) {};
}

它从不调用 cond.signalAll(),因此在 index=0 的线程通过后,其他线程将永远停放。

  • 第三个问题是在if(index != x) {.. block 中,cond.signalAll()lock.unlock() 顺序错误:
lock.unlock();
cond.signalAll();

ConditionsignalAll() 方法 documentation状态:

An implementation may (and typically does) require that the current thread hold the lock associated with this Condition when this method is called. Implementations must document this precondition and any actions taken if the lock is not held. Typically, an exception such as IllegalMonitorStateException will be thrown.

这两行代码必须顺序调换,否则会抛出IllegalMonitorStateException

该方法的工作版本可能如下所示:

public void finished(int x, double sum) throws InterruptedException {
try {
lock.lock();
while (index != x) {
cond.await();
}
System.out.printf("%9.2f ", sum);
index++;
cond.signalAll();
} finally {
lock.unlock();
}
if (index % 5 == 0) System.out.println();
}

有趣的是,OP 提供的代码实际上即使存在所有这些错误也能正常工作,但这只是由于 MatrixMultiTest 类中的这段代码:

try {
myThr.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

每个线程都被创建,然后按顺序启动和加入,因此在任何时刻只有一个线程尝试获取同步 finished() 方法上的隐式锁,并且 i *5+j 索引值确保线程按照它们的 index 顺序获取此隐式锁:0、1、2 等。这意味着在方法内部,index总是等于x,每个线程都经过finished()中的else block ,让程序完成执行。 cond.await() 实际上从未被调用。

如果删除 join block ,则可能会打印一些值,但程序最终会死锁。

关于java - Java中的多线程矩阵乘法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48582591/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com