首页 > 代码库 > Object.wait和notify方法

Object.wait和notify方法

Object.wait和notify方法


object‘s monitor

先来了解一下Object.wait和notify方法

?wait、notify和notifyAll方法是Object类的final native方法,所以这些方法不能被子类重写。?

Object类是所有类的超类,因此在程序中有以下三种形式调用wait等方法:

  1. wait();//方式1:

  2. this.wait();//方式2:

  3. super.wait();//方式3


void notifyAll()

     * Wakes up all threads that are waiting on this object‘s monitor. A thread waits on an object‘s monitor by calling one of the

     * {@code wait} methods.

该方法只能在同步方法或同步块内部调用。如果当前线程不是锁的持有者,该方法抛出一个IllegalMonitorStateException异常。


void notify()

     * 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 {@code wait} methods.

该方法只能在同步方法或同步块内部调用。如果当前线程不是锁的持有者,该方法抛出一个IllegalMonitorStateException异常。


void wait()

     * Causes the current thread to wait until another thread invokes the

     * {@link java.lang.Object#notify()} method or the

     * {@link java.lang.Object#notifyAll()} method for this object.

     * The current thread must own this object‘s monitor. 

导致线程进入等待状态,直到它被其他线程通过notify()或者notifyAll唤醒。该方法只能在同步方法中调用。如果当前线程不是锁的持有者,该方法抛出一个IllegalMonitorStateException异常。

下面是一个wait的示例

synchronized (object) {
   while (<condition does not hold>)
      object.wait(timeout);
   ... // Perform action appropriate to condition
}


void wait(long millis)和void wait(long millis,int nanos)

     * Causes the current thread to wait until another thread invokes the

     * {@link java.lang.Object#notify()} method or the

     * {@link java.lang.Object#notifyAll()} method for this object, or

     * some other thread interrupts the current thread, or a certain

     * amount of real time has elapsed(消逝,过去).

这些方法只能在同步方法中调用。如果当前线程不是锁的持有者,该方法抛出一个IllegalMonitorStateException异常。


?Object.wait()和Object.notify()和Object.notify()必须写在synchronized方法内部或者synchronized块内部,这是因为:这几个方法要求当前正在运行object.wait()方法的线程拥有object的对象锁(内置锁)。即使你确实知道当前上下文线程确实拥有了对象锁,也不能将object.wait()这样的语句写在当前上下文中。?

下面这段代码的写法是错误的。。

package sync;

class A {
    public synchronized void printThreadInfo() throws InterruptedException {
        Thread t = Thread.currentThread();
        System.out.println("ThreadID:" + t.getId() + ", ThreadName:" + t.getName());
    }
}


public class ObjectWaitTest {
    public static void main(String args[]) {
        A a = new A();
        //因为printThreadInfo()方法抛出InterruptedException异常,所以这里必须使用try-catch块
        try {
            a.printThreadInfo();
            a.wait();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

应该要这么写:

package sync;

class A {
    public synchronized void printThreadInfo() throws InterruptedException {
        Thread t = Thread.currentThread();
        System.out.println("ThreadID:" + t.getId() + ", ThreadName:" + t.getName());
        // this.wait();//一直等待
        this.wait(1000);//等待1000ms
        // super.wait(1000);
    }
}


public class ObjectWaitTest {
    public static void main(String args[]) {
        A a = new A();
        //因为printThreadInfo()方法抛出InterruptedException异常,所以这里必须使用try-catch块
        try {
            a.printThreadInfo();
            //a.wait();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        Thread t = Thread.currentThread();
        System.out.println("ThreadID:" + t.getId() + ", ThreadName:" + t.getName());
    }
}


以上就是关于wait和notify方法的用法,具体请参见:http://www.cnblogs.com/xwdreamer/archive/2012/05/12/2496843.html

后记:Thread.sleep()与Object.wait()二者都可以暂停当前线程,释放CPU控制权,主要的区别在于Object.wait()在释放CPU同时,释放了对象锁的控制。


=========================END=========================


Object.wait和notify方法