1
class myThreadRun implements Runnable
{

    public void run() {
        roo();
    }
    public synchronized void roo()
    {
        System.out.println("In thread before wait " + Thread.currentThread().getName());
        try {
            wait();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        JOptionPane.showMessageDialog(null, "After wait in\n"+Thread.currentThread().getName());
        System.out.println("In thread after wait " + Thread.currentThread().getName());
        //notify();
    }

    public synchronized void foo()
    {
        notify();
    }
}

public class ThreadingDemo {

    public synchronized void Start()
    {
        System.out.println("Labamba");
        myThreadRun mThRun =  new myThreadRun();
        Thread thread =  new Thread(mThRun);
        thread.start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        //mThRun.foo(); //This works
        //mThRun.notify(); //crash
        //thread.notify();//crash
        try {
            thread.join();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
public static  void main(String[] args) {
        new ThreadingDemo().Start();
    }

这是演示 wait() 和 notify() 的简单代码,如果我执行 mThRun.notify( ) 程序崩溃,但 mThRun.foo() 运行顺利并给出了急需的结果。我需要知道为什么?

4

3 回答 3

2

您需要拥有所有对象的监视器obj.wait()obj.notify().

这就是为什么它在synchronized块内部mThRun而不是外部调用时起作用的原因。所以如果你把它mThRun.notify();放在一个同步块中,它就可以工作,就像这样:

synchronized (mThRun) {
    mThRun.notify();
}
于 2012-08-28T08:23:13.393 回答
1

In your case you are getting an IllegalMonitorStateException.

Thrown to indicate that a thread has attempted to wait on an object's monitor or to notify other threads waiting on an object's monitor without owning the specified monitor.

Put another way, you don't hold the lock of the object you are trying to notify. Having the lock of a different object doesn't help.


When you use notify() and wait() you need to change a state and check for it. If you don't do this, you can find that either

  • notify() is called before wait() and the signal is lost
  • wait() wakes prematurely

You cannot assume notify/wait is a reliable messaging protocol.

I suggest you consider using the concurrency library which is a better choice in most cases from Java 5.0 (2004)

于 2012-08-28T08:26:06.383 回答
0

可能是您在等待/通知方面非常努力。它非常简单。您需要知道的是哪个对象用于监视器锁定。为了使相同的代码正常工作,我修改了相同的代码:(我在更改代码的地方添加了 MAK 注释,希望对您有所帮助)

class MyThreadRun implements Runnable {
    public void run() {
        roo();
    }
    public synchronized void roo() {
        System.out.println("In thread before wait " + this);
        try {
            wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        JOptionPane.showMessageDialog(null, "After wait in\n" + Thread.currentThread().getName());
        System.out.println("In thread after wait " + Thread.currentThread().getName());
    }

}

public class ThreadingDemo {

    public static void main(String[] args) {
        MyThreadRun mThRun = new MyThreadRun();
        System.out.println("Labamba: " +mThRun);
        Thread thread = new Thread(mThRun);
        thread.start();
        try {
            Thread.sleep(100);
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }
        //mThRun.foo(); //This works  //MAK: no sense
        //mThRun.notify(); //crash   //MAK: Need monitor lock
        synchronized (mThRun) {
            mThRun.notify();//crash                  //MAK: will work now
        }
        try {
            thread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}
于 2013-11-28T13:42:26.803 回答