简体   繁体   English

Java Threading wait()和Notify()似乎特别有用

[英]A Java Threading wait() and Notify() seems to work peculiarly

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();
    }

This is simple code to demonstrate wait() and notify(), In the myThreadRun class run() method just does wait() and foo() method does notify() as indicated in the code above, if I do mThRun.notify() the program crashes, but mThRun.foo() runs the without a hitch and gives the much needed result. 这是演示wait()和notify()的简单代码,在myThreadRun类中,run()方法只是执行wait()和foo()方法,如上面的代码所示,发出notify(),如果我执行mThRun.notify(程序崩溃了,但是mThRun.foo()顺利运行并提供了急需的结果。 I need to know why? 我需要知道为什么?

You need to own the monitor for the object to all obj.wait() and obj.notify() . 您需要将对象的监视器拥有到所有obj.wait()obj.notify()

That is why it works when called within the synchronized block on mThRun but not outside. 这就是为什么它在mThRun上的synchronized块内mThRun但不在外面调用的原因。 So if you put the mThRun.notify(); 所以如果你把mThRun.notify(); in a synchronized block, it works, like this: 在同步块中,它的工作方式如下:

synchronized (mThRun) {
    mThRun.notify();
}

In your case you are getting an IllegalMonitorStateException . 在您的情况下,您将收到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. 当您使用notify()和wait()时,您需要更改状态并检查它。 If you don't do this, you can find that either 如果你不这样做,你也可以找到

  • notify() is called before wait() and the signal is lost 在wait()之前调用notify()并且信号丢失
  • wait() wakes prematurely wait()过早地醒来

You cannot assume notify/wait is a reliable messaging protocol. 您不能假设notify / wait是一种可靠的消息传递协议。

I suggest you consider using the concurrency library which is a better choice in most cases from Java 5.0 (2004) 我建议你考虑使用并发库,这在Java 5.0(2004)的大多数情况下是更好的选择。

May be you are going very hard with wait/notify. 也许你正在努力等待/通知。 Its very simple. 它非常简单。 what you need to know is which object is used for monitor lock. 您需要知道的是哪个对象用于监视器锁定。 To make the same code working i have modified the same code: ( I have put MAK comment where i changed the code, hope its helpful) 为了使相同的代码工作,我修改了相同的代码:(我把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();
        }

    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM