猿问

如何在Java中使用等待和通知而不使用IllegalMonitorStateException?

如何在Java中使用等待和通知而不使用IllegalMonitorStateException?

我有两个矩阵,我需要把它们相乘,然后打印每个细胞的结果。一旦一个单元格准备就绪,我就需要打印它,但例如,我需要在单元格[2][0]之前打印[0]单元格,即使[2][0]的结果先准备好。所以我需要按顺序打印。所以我的想法是让打印机线程等到multiplyThread通知它,正确的单元格已准备好打印,然后printerThread将打印出手机,然后返回等待等等。

所以我有一条线来做乘法:

public void run() {
    int countNumOfActions = 0; // How many multiplications have we done
    int maxActions = randomize(); // Maximum number of actions allowed

    for (int i = 0; i < size; i++)
    {       
        result[rowNum][colNum] = result[rowNum][colNum] + row[i] * col[i];
        countNumOfActions++;
        // Reached the number of allowed actions
        if (countNumOfActions >= maxActions)
        {
            countNumOfActions = 0;
            maxActions = randomize();
            yield();
        }   
    }
    isFinished[rowNum][colNum] = true;
    notify();}

打印每个单元格的结果的线程:

public void run(){
    int j = 0; // Columns counter
    int i = 0; // Rows counter
    System.out.println("The result matrix of the multiplication is:");

    while (i < creator.getmThreads().length)
    {
        synchronized (this)
        {
            try 
            {
                this.wait();
            } 
            catch (InterruptedException e1) 
            {
            }
        }
        if (creator.getmThreads()[i][j].getIsFinished()[i][j] == true)
        {
            if (j < creator.getmThreads()[i].length)
            {
                System.out.print(creator.getResult()[i][j] + " ");
                j++;
            }
            else
            {
                System.out.println();
                j = 0;
                i++;
                System.out.print(creator.getResult()[i][j] + " ");
            }
        }
    }

现在它抛出了这些例外:

Exception in thread "Thread-9" java.lang.IllegalMonitorStateException
    at java.lang.Object.notify(Native Method)
    at multiplyThread.run(multiplyThread.java:49)Exception in thread "Thread-6" Exception in thread "Thread-4"
     java.lang.IllegalMonitorStateException
   
    如果有人能帮助这段代码工作,我会非常感激的。


隔江千里
浏览 425回答 3
3回答

繁华开满天机

能够打电话通知()您需要在同一个对象上同步。synchronized&nbsp;(someObject)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;someObject.wait();}/*&nbsp;different&nbsp;thread&nbsp;/&nbsp;object&nbsp;*/synchronized&nbsp;(someObject)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;someObject.notify();}

手掌心

在使用wait和notify或notifyAll方法必须记住以下几点:使用notifyAll而不是notify如果您期望有多个线程正在等待一个锁。这个wait和notify方法必须在同步上下文中调用。..有关更详细的解释,请参阅链接。总是调用wait()方法,因为如果多个线程正在等待锁,其中一个线程获得锁并重置条件,则其他线程需要在醒来后检查条件,以确定是否需要再次等待或开始处理。使用相同的对象调用wait()和notify()方法;每个对象都有自己的锁,因此调用wait()关于客体A和notify()对目标B没有任何意义。

哆啦的时光机

您需要线程吗?我想知道你的矩阵有多大,一个线程打印,另一个做乘法是否有好处。也许在做相对复杂的线程工作之前,这一次是值得衡量的吗?如果您确实需要线程,我将创建‘n’线程来执行细胞的增殖(也许‘n’是可用的核数),然后使用行政服务和未来同时分配多个乘法的机制。这样,您就可以根据内核的数量来优化工作,并且使用更高级的Java线程工具(这将使工作变得更容易)。将结果写回接收矩阵,然后在您的未来任务完成后,只需打印此结果即可。
随时随地看视频慕课网APP

相关分类

Java
我要回答