首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在没有IllegalMonitorStateException的Java中使用等待和通知?

如何在没有IllegalMonitorStateException的Java中使用等待和通知?
EN

Stack Overflow用户
提问于 2009-05-20 08:04:54
回答 8查看 237.6K关注 0票数 132

我有两个矩阵,我需要将它们相乘,然后打印每个单元格的结果。一旦一个单元格准备好了,我就需要打印它,但是例如,我需要打印单元格2之前的单元格,即使2的结果已经准备好了。所以我需要按顺序打印它。所以我的想法是让打印线程等待,直到multiplyThread通知它准备打印正确的单元格,然后printerThread将打印单元格并返回等待,依此类推。

所以我有这个线程来做乘法:

代码语言:javascript
复制
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();
}

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

代码语言:javascript
复制
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] + " ");
            }
        }
    }

现在它抛给我这些异常:

代码语言:javascript
复制
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
    at java.lang.Object.notify(Native Method)
    at multiplyThread.run(multiplyThread.java:49)
java.lang.IllegalMonitorStateException
    at java.lang.Object.notify(Native Method)
    at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-5" java.lang.IllegalMonitorStateException
    at java.lang.Object.notify(Native Method)
    at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-8" java.lang.IllegalMonitorStateException
    at java.lang.Object.notify(Native Method)
    at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-7" java.lang.IllegalMonitorStateException
    at java.lang.Object.notify(Native Method)
    at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-11" java.lang.IllegalMonitorStateException
    at java.lang.Object.notify(Native Method)
    at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-10" java.lang.IllegalMonitorStateException
    at java.lang.Object.notify(Native Method)
    at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-12" java.lang.IllegalMonitorStateException
    at java.lang.Object.notify(Native Method)
    at multiplyThread.run(multiplyThread.java:49)

multiplyThread中的49行是“notify()”,..I认为我需要以不同的方式使用synchronized,但我不确定如何使用。

如果有人能帮助这段代码工作,我将不胜感激。

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2009-05-20 08:21:53

为了能够调用notify(),您需要在同一对象上进行同步。

代码语言:javascript
复制
synchronized (someObject) {
    someObject.wait();
}

/* different thread / object */
synchronized (someObject) {
    someObject.notify();
}
票数 219
EN

Stack Overflow用户

发布于 2009-05-20 08:34:38

你真的需要把它挂起来吗?我想知道你的矩阵有多大,以及让一个线程打印另一个线程进行乘法是否有任何好处。

也许在做相对复杂的线程化工作之前,这一次是值得的?

如果您确实需要将其线程化,我将创建'n‘个线程来执行单元的乘法运算(可能'n’是您可以使用的核心数量),然后使用ExecutorServiceFuture机制同时分派多个乘法运算。

这样,您就可以根据内核数量优化工作,并使用更高级别的Java线程工具(这将使工作更容易)。将结果写回接收矩阵,然后在所有将来的任务完成后简单地打印出来。

票数 21
EN

Stack Overflow用户

发布于 2012-10-16 06:25:20

假设您有一个“黑盒”应用程序,其中包含一些具有doSomething();方法的名为BlackBoxClass的类。

此外,BlackBoxClass将在未知时间之后调用名为onResponse(String resp)的观察者或侦听器。

流程很简单:

代码语言:javascript
复制
private String mResponse = null; 
 ...
BlackBoxClass bbc = new BlackBoxClass();
   bbc.doSomething();
...
@override
public void onResponse(String resp){        
      mResponse = resp;       
}

假设我们不知道BlackBoxClass是怎么回事,什么时候应该得到应答,但是你不想继续你的代码,直到你得到应答,或者换句话说,得到onResponse调用。这里输入'Synchronize helper':

代码语言:javascript
复制
public class SyncronizeObj {
public void doWait(long l){
    synchronized(this){
        try {
            this.wait(l);
        } catch(InterruptedException e) {
        }
    }
}

public void doNotify() {
    synchronized(this) {
        this.notify();
    }
}

public void doWait() {
    synchronized(this){
        try {
            this.wait();
        } catch(InterruptedException e) {
        }
    }
}
}

现在我们可以实现我们想要的东西了:

代码语言:javascript
复制
public class Demo {

private String mResponse = null; 
 ...
SyncronizeObj sync = new SyncronizeObj();

public void impl(){

BlackBoxClass bbc = new BlackBoxClass();
   bbc.doSomething();

   if(mResponse == null){
      sync.doWait();
    }

/** at this momoent you sure that you got response from  BlackBoxClass because
  onResponse method released your 'wait'. In other cases if you don't want wait too      
  long (for example wait data from socket) you can use doWait(time) 
*/ 
...

}


@override
public void onResponse(String resp){        
      mResponse = resp;
      sync.doNotify();       
   }

}
票数 14
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/886722

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档