wait/notify是Object下的一個方法。
wait方法是使當前執行代碼的線程進行等待,該方法用來將當前線程置入「預執行隊列」中,而且在wait所在的代碼行處中止執行,直到接到通知或被中斷爲止。在調用wait以前,線程必須得到該對象的的對象級別鎖,即只能在同步方法或同步塊中調用wait()方法。若是沒有得到鎖就會拋出illegalMonitorStateException.執行完wiat後鎖馬上被釋放。
notify也要在同步方法或同步塊中調用,也就是說調用以前也必須得到鎖。該方法用來通知那些可能等待對象的對象鎖的其餘線程,若是有多個線程等待,則由線程規劃器隨機挑選出其中一個呈wait狀態的線程,須要說明的是,在執行notify方法後,當前線程不會立刻釋放該對象鎖,呈wait狀態的線程也並不能立刻獲取鎖,要等到notify方法的線程執行完。
1.若是一個wait沒有獲得notify或notifyAll即使對象已經空閒,還會繼續阻塞在wait狀態,總wait是使用線程中止運行;而notify使中止的線程斷續運行。
2.當線程呈wait狀態時,調用線程對象的interrupt方法會出現InterruptedException
3.當有線程還未處理wait狀態下就發出notify,notiyf就等於一個空方法 java
測試1:
ide
private static String lock = "lock"; public static void main(String[] args) throws InterruptedException { new Thread(){ @Override public void run() { synchronized(lock){ System.out.println("thread running"); try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("thread end"); } } }.start(); Thread.sleep(2000); synchronized(lock){ System.out.println("send notify"); lock.notify(); } }
結果:
thread running
send notify
thread end
測試
測試2: spa
public static void main(String[] args) throws InterruptedException { Thread t = new Thread(){ @Override public synchronized void run() { System.out.println("thread running"); try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("thread end"); } }; t.start(); Thread.sleep(2000); synchronized(t){ System.out.println("send notify"); t.notify(); } }
結果:
thread running
send notify
thread end 線程
測試3: code
public static class Company{ volatile private boolean consumeFirst = false; //生產 public synchronized void product(){ try { while(consumeFirst){ wait(); } System.out.println("★★★★★"); consumeFirst = true; notifyAll(); } catch (InterruptedException e) { // TODO Auto-generated catch block } } //消費 public synchronized void consume(){ try { while(!consumeFirst){ wait(); } System.out.println("☆☆☆☆☆"); consumeFirst = false; notifyAll(); } catch (InterruptedException e) { // TODO Auto-generated catch block } } } public static void main(String[] args) { final Company company = new Company(); for (int i = 0; i < 10; i++) { Thread consume = new Thread(){ public void run() { company.consume(); }; }; consume.start(); Thread product = new Thread(){ public void run() { company.product(); }; }; product.start(); } }
結果:
★★★★★
☆☆☆☆☆
★★★★★
☆☆☆☆☆
★★★★★
☆☆☆☆☆
... 對象