1. 程式人生 > >Java 執行緒的通訊 wait() 與 notify() 和 notifyAll()的使用

Java 執行緒的通訊 wait() 與 notify() 和 notifyAll()的使用

@[toc](Java 執行緒的通訊 wait() 與 notify() 和 notifyAll()的使用)

1. 執行緒通訊

  1. wait() 與 notify() 和 notifyAll()
    ① wait():令當前執行緒掛起並放棄CPU、同步資源,使別的執行緒可訪問並修改共享資源,而當前執行緒排隊等候再次對資源的訪問
    ② notify():喚醒正在排隊等待同步資源的執行緒中優先順序最高者結束等待
    ③ notifyAll ():喚醒正在排隊等待資源的所有執行緒結束等待.
  2. Java.lang.Object提供的這三個方法只有在synchronized方法或synchronized程式碼塊中才能使用,否則會報java.lang.IllegalMonitorStateException異常

2.wait() 方法

  1. 在當前執行緒中呼叫方法: 物件名.wait()
  2. 使當前執行緒進入等待(某物件)狀態 ,直到另一執行緒對該物件發出 notify (或notifyAll) 為止。
  3. 呼叫方法的必要條件:當前執行緒必須具有對該物件的監控權(加鎖)
  4. 呼叫此方法後,當前執行緒將釋放物件監控權 ,然後進入等待
  5. 在當前執行緒被notify後,要重新獲得監控權,然後從斷點處繼續程式碼的執行。

3. notify()/notifyAll()

  1. 在當前執行緒中呼叫方法: 物件名.notify()
  2. 功能:喚醒等待該物件監控權的一個執行緒。
  3. 呼叫方法的必要條件:當前執行緒必須具有對該物件的監控權(加鎖)

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();
	}
}