Java wait && notifyhtml
wait、notify和notifyAll方法是Object类的final native方法,因此这些方法不能被子类重写。java
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{wait} methods.ide
该方法只能在同步方法或同步块内部调用。若是当前线程不是锁的持有者,该方法抛出一个IllegalMonitorStateException异常。this
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.spa
该方法只能在同步方法或同步块内部调用。若是当前线程不是锁的持有者,该方法抛出一个IllegalMonitorStateException异常。线程
Causes the current thread to wait until another thread invokes the {java.lang.Object#notify()} method or the {java.lang.Object#notifyAll()} method for this object.The current thread must own this object's monitor. code
调用该方法的线程进入WAITING 状态,只有等待另外线程的通知或被中断才会返回,须要注意的是调用wait方法后,才会释放对象的锁。orm
该方法只能在同步方法中调用。若是当前线程不是锁的持有者,该方法抛出一个IllegalMonitorStateException异常。下面是一个wait的示例htm
synchronized (object) { while (<condition does not hold>) object.wait(); // ... }
Causes the current thread to wait until another thread invokes the { java.lang.Object#notify()} method or the {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(消逝,过去).对象
超时等待一段时间后,这里的参数时间是毫秒,也就是等待长达n毫秒,若是没有通知就超时返回。
这些方法只能在同步方法中调用。若是当前线程不是锁的持有者,该方法抛出一个IllegalMonitorStateException异常。
timeout -- 最大的等待时间(以毫秒为单位)。
nanos -- 额外的时间,在纳秒范围为0-999999。
Object.wait()和Object.notify()和Object.notifyAll()必须写在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(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } Thread t = Thread.currentThread(); System.out.println("ThreadID:" + t.getId() + ", ThreadName:" + t.getName()); } }
完整示例,
import java.text.SimpleDateFormat; import java.util.Date; import java.util.concurrent.TimeUnit; public class WaitNotifyDemo { static boolean flag = true; static Object lock = new Object(); public static void main(String[] args) throws InterruptedException { Thread waitThread = new Thread(new Wait(), "waitThread"); waitThread.start(); TimeUnit.SECONDS.sleep(1); Thread notifyThread = new Thread(new Notify(), "notifyThread"); notifyThread.start(); } static class Wait implements Runnable { @Override public void run() { // 加锁 拥有lock 的 monitor synchronized (lock) { while (flag) { try { System.out.println(Thread.currentThread() + " flag is true. wait @ " + new SimpleDateFormat("HH:mm:ss").format(new Date())); // 释放了对象的监视器锁 lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(Thread.currentThread() + " flag is false. running @ " + new SimpleDateFormat("HH:mm:ss").format(new Date())); } } } static class Notify implements Runnable { @Override public void run() { synchronized (lock) { System.out.println(Thread.currentThread() + " hold lock. notify @ " + new SimpleDateFormat("HH:mm:ss").format(new Date())); lock.notifyAll(); flag = false; try { Thread.sleep(1000 * 5); } catch (InterruptedException e) { e.printStackTrace(); } } } } }
以上就是关于wait和notify方法的用法。
参考:http://www.cnblogs.com/xwdreamer/archive/2012/05/12/2496843.html
后记:Thread.sleep()与Object.wait()两者均可以暂停当前线程,释放CPU控制权,主要的区别在于Object.wait()在释放CPU同时,释放了对象锁的控制。
==============END==============