線程等待/通知機制的實現

  • 方法wait()使當前線程等待,釋放鎖,並且在wait方法處停止執行,直到接到通知或被中斷爲止;
  • 調用wai()方法前必須獲得該對象的對象級別鎖,如果調用wait()時沒有適當的鎖,拋出IllegalMonitorStateException。
  • notify()調用時也必須獲得該對象的對象級別鎖,若沒有,拋出IllegalMonitorStateException;
  • notify()方法用來通知那些可能等待該對象的對象鎖的其他線程,若有多個,由線程規劃器挑選一個,並使它獲得該對象的對象鎖;
  • 執行notify()後,當前線程並不馬上釋放鎖,wait狀態線程也並不能馬上獲得鎖,要等到notiry()方法的線程執行完退出synchronized塊後纔行。

一個例子

/**
 * 等待通知機制的實現
 * @author user1
 *
 */
public class MyList313 {

	private List<String> list = new ArrayList<>();
	public void add(){
		list.add("景");
	}
	public int getSize(){
		return list.size();
	}
	
	public void m1(){
		synchronized(list){
			try {
				if(list.size() != 5){
					System.out.println("進入m1 wait"+System.currentTimeMillis());
					list.wait();
					System.out.println("離開m1 wait"+System.currentTimeMillis());
				}
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
	public void m2(){
		synchronized(list){
			for(int i = 0;i<10;i++){
				add();
				if(list.size() == 5){
						System.out.println("進入m2 notify"+System.currentTimeMillis());
						list.notify();
						System.out.println("離開m2 notify"+System.currentTimeMillis());
				}
				System.out.println("m2 中list的長度"+getSize());
				try {
					Thread.sleep(2000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	public static void main(String[] args) {
		MyList313 m = new MyList313();
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				m.m1();
			}
		}).start();
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		new Thread(new Runnable() {
			@Override
			public void run() {
				m.m2();
			}
		}).start();
	}
	
}

結果
在這裏插入圖片描述
notifyAll()方法可以使所有正在等待隊列等待同一資源的全部線程從等待狀態退出,進入可運行狀態。此時,優先級最高的最先運行,但也有可能隨機運行。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章