Java 執行緒的通訊 wait() 與 notify() 和 notifyAll()的使用
阿新 • • 發佈:2018-12-18
@[toc](Java 執行緒的通訊 wait() 與 notify() 和 notifyAll()的使用)
1. 執行緒通訊
- wait() 與 notify() 和 notifyAll()
① wait():令當前執行緒掛起並放棄CPU、同步資源,使別的執行緒可訪問並修改共享資源,而當前執行緒排隊等候再次對資源的訪問
② notify():喚醒正在排隊等待同步資源的執行緒中優先順序最高者結束等待
③ notifyAll ():喚醒正在排隊等待資源的所有執行緒結束等待. - Java.lang.Object提供的這三個方法只有在synchronized方法或synchronized程式碼塊中才能使用,否則會報java.lang.IllegalMonitorStateException異常
2.wait() 方法
- 在當前執行緒中呼叫方法: 物件名.wait()
- 使當前執行緒進入等待(某物件)狀態 ,直到另一執行緒對該物件發出 notify (或notifyAll) 為止。
- 呼叫方法的必要條件:當前執行緒必須具有對該物件的監控權(加鎖)
- 呼叫此方法後,當前執行緒將釋放物件監控權 ,然後進入等待
- 在當前執行緒被notify後,要重新獲得監控權,然後從斷點處繼續程式碼的執行。
3. notify()/notifyAll()
- 在當前執行緒中呼叫方法: 物件名.notify()
- 功能:喚醒等待該物件監控權的一個執行緒。
- 呼叫方法的必要條件:當前執行緒必須具有對該物件的監控權(加鎖)
4.經典例題:使用兩個執行緒列印 1-100. 執行緒1, 執行緒2 交替列印
//使用兩個執行緒列印1-100,執行緒1,執行緒2,交替列印 class PrintNum implements Runnable{ int num = 1; @Override public void run() { while(true) { synchronized (this) { notify(); if (num <= 100) { try { Thread.currentThread().sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + ":" + num); num++; } else { break; } try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } } public class TestCommunication { public static void main(String[] args) { PrintNum p = new PrintNum(); Thread t1 = new Thread(p); Thread t2 = new Thread(p); t1.setName("執行緒1"); t2.setName("執行緒2"); t1.start(); t2.start(); } }