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==============