【问题标题】:wait() call in java codejava代码中的wait()调用
【发布时间】:2012-12-02 14:13:13
【问题描述】:
public class newTest{

/**
 * @param args
 */
public static Integer x = new Integer(0);

public static void main(String[] args) {
    newTest tstobj = new newTest();
    // TODO Auto-generated method stub
    MyThread t = tstobj.new MyThread();
    t.start();
    tstobj.incrementX();
    System.out.println(x.intValue());
    try {
        t.join();
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

public synchronized void incrementX(){
    try {
        while(x != 5){
            x.wait();
        }
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}



public class MyThread extends Thread{
    newTest tstobj = new newTest();
    public void run() {
        // TODO Auto-generated method stub      
        tstobj.incrementX();
    }
}

}

我不确定为什么这段代码会导致 IllegalMonitorStateException 而不是无限循环。具体来说,这段代码有两个线程 1. 主线程 2. MyThread 他们都尝试调用一个名为 incrementX() 的同步方法,所以假设两个线程之一通过获取锁进入同步方法,然后它看到 x != 5 所以它调用等待,这将释放锁并将放置在等待队列中,等待调用同步方法的下一个线程将通过获取锁进入并看到 x != 5 并调用等待,这将挂起线程并放入等待队列。现在两个线程在等待队列中什么都不做,这应该会导致一个无限循环。但是这段代码会导致非法MonitorStateException?

这段代码不会做任何有用的事情,但我想了解我在概念上哪里出错了?我查看了很多材料,但仍然无法弄清楚我对代码的期望有什么问题。任何帮助都会很棒。谢谢

【问题讨论】:

  • 关键错误是在与您调用其等待方法的对象不同的对象上同步。将方法标记为“已同步”等同于对此进行同步。它可能有助于停止写作,并且可能会以“同步”的方式思考,而改为以“同步于...”的方式思考。

标签: java multithreading object wait


【解决方案1】:

只需将您的 wait 呼叫更改为:-

wait();  // or `this.wait()

您只能在已锁定的对象上调用waitnotify 方法。因此,当您调用 synchronized 方法时,您实际上将锁定 this 引用指向的对象。因此,您需要在 this 引用上调用 wait()

在使用waitnotify 方法时,您可以遵循以下两条规则:-

  • 同步方法始终锁定this 引用。
  • 同步块可以锁定任何引用,具体取决于括号中使用的对象引用。

示例(同步块):-

synchonized(obj) {    // Locks `obj`
    obj.wait();       // Invoke wait on obj
}

【讨论】:

    【解决方案2】:

    要首先在某个对象上调用wait(),您必须为该对象获取lock。所以首先

    synchronize(x){
    
        //some code
    
        x.wait();
    
    }
    

    【讨论】:

      猜你喜欢
      • 2021-09-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-01
      • 1970-01-01
      • 2012-05-10
      • 1970-01-01
      • 2011-08-18
      相关资源
      最近更新 更多