Java中wait与notify的正确使用

       今天编程时遇到一个wait方法调用时抛出IIIegalMonitorStateException异常,所以再把wait和notify的用法整理一遍。

       首先,多线程同步问题既有多线程对资源的竞争问题,也有多线程之间的协同问题。在这里我们仅讨论多线程的协同问题。

1、wait()与notifyAll()

       wait()在Java doc中的描述为:

Causes the current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object. In other words, this method behaves exactly as if it simply performs the call wait(0).

The current thread must own this object's monitor. The thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object's monitor to wake up either through a call to the notify method or the notifyAllmethod. The thread then waits until it can re-obtain ownership of the monitor and resumes execution.

As in the one argument version, interrupts and spurious wakeups are possible, and this method should always be used in a loop:
     synchronized (obj) {
         while (<condition does not hold>)
             obj.wait();
         ... // Perform action appropriate to condition
     }

This method should only be called by a thread that is the owner of this object's monitor. See the notify method for a description of the ways in which a thread can become the owner of a monitor.

     

上述描述说明,wait()方法只能在拥有指定对象的控制权时才能被调用。具体怎么样获得对象的控制权,要参看notify方法的描述。

    notify()在java doc中的描述为:

Wakes up a single thread that is waiting on this object's monitor. If any threads are waiting on this object, one of them is chosen to be awakened. The choice is arbitrary and occurs at the discretion of the implementation. A thread waits on an object's monitor by calling one of the wait methods.
The awakened thread will not be able to proceed until the current thread relinquishes the lock on this object. The awakened thread will compete in the usual manner with any other threads that might be actively competing to synchronize on this object; for example, the awakened thread enjoys no reliable privilege or disadvantage in being the next thread to lock this object.

This method should only be called by a thread that is the owner of this object's monitor. A thread becomes the owner of the object's monitor in one of three ways:

By executing a synchronized instance method of that object.
By executing the body of a synchronized statement that synchronizes on the object.
For objects of type Class, by executing a synchronized static method of that class.
Only one thread at a time can own an object's monitor.

  

    上述描述说明,notify()方法会随机唤醒一个等待对象的线程,被唤醒的线程只有在调用notify()的线程释放对象锁后才可能执行,另外被唤醒的线程与其他等待该对象锁的线程都同等的概率称为获得对象锁的下一个线程。

   notify()方法也只能在拥有对象控制权的线程中被调用,一个线程称为对象控制权的所有者的方法有三种:

   * 执行该对象的同步的实例方法

   * 执行该对象的同步块

   * 对于该对象的类,执行该类的静态同步方法


      综上可知,wait()和notify()方法、notifyAll()方法在调用时必须放在同步代码中。如果在非同步控制方法中调用这些方法,程序能编译通过,但是运行时将得到IIIegalMonitorStateException异常。

      wait()的用法如下:

synchronized (obj) {
    while (<condition does not hold>)
         obj.wait();

    ... // Perform action appropriate to condition
 }

     notify的用法如下:

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








  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值