object‘s monitor
先来了解一下Object.wait和notify方法
?wait、notify和notifyAll方法是Object类的final native方法,所以这些方法不能被子类重写。?
Object类是所有类的超类,因此在程序中有以下三种形式调用wait等方法:
- wait();//方式1:
- this.wait();//方式2:
- 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=========================