Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中的多线程矩阵乘法_Java_Multithreading_Matrix_Conditional_Wait - Fatal编程技术网

Java中的多线程矩阵乘法

Java中的多线程矩阵乘法,java,multithreading,matrix,conditional,wait,Java,Multithreading,Matrix,Conditional,Wait,我试图构建一个程序,使用a*d线程(用于打印完成的矩阵中一个索引的总和)乘以两个矩阵(a[a,b],b[c,d]),为此,我使用了一个“monitor”类,该类将用作控制器来同步线程之间的大小,“乘法器”类表示单个线程和主程序类。我的想法是线程将进行计算,当线程(0,0)将打印其总和时,他将向下一行发出信号。出于某种原因,在打印第一个索引后,所有线程都处于等待模式,不会测试我的状态。你能看一下我的密码,告诉我哪里错了吗 监控类: import java.util.concurrent.locks

我试图构建一个程序,使用a*d线程(用于打印完成的矩阵中一个索引的总和)乘以两个矩阵(a[a,b],b[c,d]),为此,我使用了一个“monitor”类,该类将用作控制器来同步线程之间的大小,“乘法器”类表示单个线程和主程序类。我的想法是线程将进行计算,当线程(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();
        }
    }
}
公共类乘数扩展线程{
私有整数索引;
专用双[]矢量;
私人双【】vectorTwo;
私人监听;
私人双和;
//建造师
公共乘数(整数索引、监视器监视器、双[]向量一、双[]向量二){
这个指数=指数;
this.monitor=监视器;
this.vectorOne=vectorOne;
this.vectorwo=vectorwo;
}
公共空间{
总和=0;
for(int i=0;i
主要类别:

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();
                }
            }
    }
}
公共类矩阵多重测试{
公共静态void main(字符串[]args){
监视器=新监视器(3*5);
矩阵A=矩阵随机(3,4);
矩阵B=矩阵随机(4,5);
系统输出打印项次(“矩阵1”);
A.show();
System.out.println();
系统输出打印项次(“矩阵No2”);
B.show();
System.out.println();
System.out.println(“多矩阵”);
对于(int i=0;i<3;i++)
对于(int j=0;j<5;j++){
乘数MyTR=新的乘数(i*5+j,
监视器,A.getRow(i),B.getCol(j));
mytr.start();
试一试{
mytr.join();
}捕捉(中断异常e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
}
}
}
这个
finished()
方法充满了问题:

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

  • 第二个故障与
    else
    块有关:

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

  • 第三个问题是,在
    if(index!=x){..
    块中,
    cond.signalAll()
    lock.unlock()
    的顺序错误:
条件
signalAll()
方法声明:

调用此方法时,实现可能(通常确实)要求当前线程持有与此条件关联的锁。实现必须记录此前提条件以及未持有锁时所采取的任何操作。通常会引发异常,如
IllegalMonitorStateException

必须按顺序切换这两行代码,否则将抛出
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();
}
每个线程都被创建,然后按顺序启动和连接,因此只有一个线程试图获取synchronized
finished()上的隐式锁
方法在任何时刻,并且
i*5+j
索引值确保线程按照其
索引的顺序获取此隐式锁:0、1、2等。这意味着在方法中,
索引始终等于
x
,并且每个线程都在
完成()
,允许程序完成执行。
cond.await()
实际上从未被调用


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

while(index!=x)
将永远不会停止,因为方法参数x和索引将永远不会更改,您需要检查所有线程共享的变量,并且java在这里是按值复制的。@zapl不是“monitor”上的索引可以被视为与所有线程共享的值吗?每当线程运行“finished”时,它都会更改。哦,ups,
索引
是索引我创建了一个共享变量。我要尝试新的乘数(i*5+j..
就其中一个而言,否则你的索引会被打个赌:如果你将多线程解决方案与简单的单线程解决方案进行基准测试,你的解决方案会慢得多…至少在10*10左右的维度上,因为你会给操作带来巨大的开销。@RalfKleberhoff可能,但这不是重点。我不是g为提高这项任务的效率而努力。
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();
}
try {
    myThr.join();
} catch (InterruptedException e) {
//  TODO Auto-generated catch block
    e.printStackTrace();
}