wait(),notify(),notifyAll()三個方法不是Thread的方法,而是Object的方法。意味着所有對象都有這三個方法,因為每個對象都有鎖,所以自然也都有操作鎖的方法了。這三個方法最終調用的都是jvm級的native方法。隨着jvm運行平台的不同可能有些許差異。
java文檔的解釋
wait導致當前的線程等待,直到其他線程調用此對象的 notify() 方法或 notifyAll() 方法。當前的線程必須擁有此對象監視器。該線程發布對此監視器的所有權並等待,直到其他線程通過調用 notify 方法,或 notifyAll 方法通知在此對象的監視器上等待的線程醒來。然后該線程將等到重新獲得對監視器的所有權后才能繼續執行.
notify喚醒在此對象監視器上等待的單個線程。如果所有線程都在此對象上等待,則會選擇喚醒其中一個線程。直到當前的線程放棄此對象上的鎖定,才能繼續執行被喚醒的線程。此方法只應由作為此對象監視器的所有者的線程來調用.
"當前的線程必須擁有此對象監視器"與"此方法只應由作為此對象監視器的所有者的線程來調用"說明wait方法與notify方法必須在同步塊內執行,即synchronized(obj之內).
調用對像wait方法后,當前線程釋放對像鎖,進入等待狀態.直到其他線程(也只能是其他線程)通過notify 方法,或 notifyAll.該線程重新獲得對像鎖.
例子代碼:
說明:線程運行3秒后調用wait等待,6秒后主線程調用notify喚醒等待線程。
1 /** 2 * Created on 2016/1/31. 3 */ 4 public class MyThread implements Runnable { 5 private Object flag; 6 private String threadName; 7 8 public MyThread(Object flag,String threadName) { 9 this.flag = flag; 10 this.threadName = threadName; 11 } 12 13 @Override 14 public void run(){ 15 try{ 16 for(int i = 0; i < 10;i++){ 17 if(i == 3){ 18 synchronized (this.flag){ 19 System.out.println("3秒后線程調用wait睡眠"); 20 this.flag.wait(); 21 } 22 } 23 System.out.println(this.threadName + " " + i); 24 Thread.sleep(1000); 25 } 26 } catch(InterruptedException e){ 27 e.printStackTrace(); 28 } 29 30 } 31 }
main方法:
1 import java.io.IOException; 2 3 /** 4 * Created on 2016/1/31. 5 */ 6 public class TestMain { 7 public static void main(String[] args) { 8 Object object = new Object(); 9 MyThread myThread1 = new MyThread(object,"thread1"); 10 // MyThread myThread2 = new MyThread(object,"thread2"); 11 Thread test1 = new Thread(myThread1); 12 test1.start(); 13 14 // Thread test2 = new Thread(myThread1); 15 // test2.start(); 16 17 try{ 18 Thread.sleep(6000); 19 System.out.println("6秒后喚醒線程"); 20 synchronized (object){ 21 object.notify(); 22 } 23 System.in.read(); 24 } catch(InterruptedException e){ 25 e.printStackTrace(); 26 } catch(IOException e){ 27 e.printStackTrace(); 28 } 29 30 } 31 }
結果:


測試notifyAll(MyThread代碼不變)
main方法代碼:
1 import java.io.IOException; 2 3 /** 4 * Created on 2016/1/31. 5 */ 6 public class TestMain { 7 public static void main(String[] args) { 8 Object object = new Object(); 9 MyThread myThread1 = new MyThread(object,"thread1"); 10 MyThread myThread2 = new MyThread(object,"thread2"); 11 Thread test1 = new Thread(myThread1); 12 test1.start(); 13 14 Thread test2 = new Thread(myThread2); 15 test2.start(); 16 17 try{ 18 Thread.sleep(6000); 19 System.out.println("6秒后喚醒線程"); 20 synchronized (object){ 21 object.notifyAll(); 22 } 23 System.in.read(); 24 } catch(InterruptedException e){ 25 e.printStackTrace(); 26 } catch(IOException e){ 27 e.printStackTrace(); 28 } 29 30 } 31 }
結果截圖:


