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

这是演示wait()和notify()的简单代码,在myThreadRun类中,run()方法只是执行wait()和foo()方法,如上面的代码所示,发出notify(),如果我执行mThRun.notify(程序崩溃了,但是mThRun.foo()顺利运行并提供了急需的结果。 我需要知道为什么?

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

这就是为什么它在mThRun上的synchronized块内mThRun但不在外面调用的原因。 所以如果你把mThRun.notify(); 在同步块中,它的工作方式如下:

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

在您的情况下,您将收到IllegalMonitorStateException

抛出此异常表示线程已尝试在对象的监视器上等待,或者在没有指定监视器的情况下通知在对象监视器上等待的其他线程。

换句话说,你没有持有你想要通知的对象的锁。 拥有不同对象的锁定无济于事。


当您使用notify()和wait()时,您需要更改状态并检查它。 如果你不这样做,你也可以找到

  • 在wait()之前调用notify()并且信号丢失
  • wait()过早地醒来

您不能假设notify / wait是一种可靠的消息传递协议。

我建议你考虑使用并发库,这在Java 5.0(2004)的大多数情况下是更好的选择。

也许你正在努力等待/通知。 它非常简单。 您需要知道的是哪个对象用于监视器锁定。 为了使相同的代码工作,我修改了相同的代码:(我把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