1. 程式人生 > >執行緒obj.wait()和obj.notify()詳解.

執行緒obj.wait()和obj.notify()詳解.

wait()和notify()同屬於Object裡面的成員方法。

Obj.wait(),與Obj.notify()必須要與synchronized(Obj)一起使用,也就是wait,與notify是針對已經獲取了Obj鎖進行操作,從語法角度來說就是Obj.wait(),Obj.notify必須在synchronized(Obj){...}語句塊內。

從功能上來說wait就是說執行緒在獲取物件鎖後,主動釋放物件鎖,同時本執行緒休眠。直到有其它執行緒呼叫物件的notify()喚醒該執行緒,才能繼續獲取物件鎖,並繼續執行。

相應的notify()就是對物件鎖的喚醒操作。但有一點需要注意的是notify()呼叫後,並不是馬上就釋放物件鎖的,而是在相應的synchronized(){}語句塊執行結束,自動釋放鎖後,JVM會在wait()物件鎖的執行緒中隨機選取一執行緒,賦予其物件鎖,喚醒執行緒,繼續執行。這樣就提供了線上程間同步、喚醒的操作。

ps:執行緒的同步通訊和互斥其實就是把用到相同程式塊的地方排序並按照執行順序的執行。

下面的程式運用到了wait()和notify()。執行緒實現同步通訊程式設計,題目:子程序先執行10次,然後主程序執行100次,並且迴圈50次。

public class TraditionalThreadCommunication {


	/**
	 * @param args
	 */
	public static void main(String[] args) {
		
		final Business business = new Business();
		new Thread(
				new Runnable() {
					
					@Override
					public void run() {
					
						for(int i=1;i<=50;i++){
							business.sub(i);
						}
						
					}
				}
		).start();
		
		for(int i=1;i<=50;i++){
			business.main(i);
		}
		
	}


}
  class Business {       
/*  實現子程序執行10次和主程序執行100次的方法,並且封裝在Business類裡面,增加了bShouldSub,
判斷是否先執行子程序,如果不是,暫停主程序(wait()),並且轉到子程序(notify())執行10次,
接著執行主程序,迴圈下去。  */
	  private boolean bShouldSub = true;
	  public synchronized void sub(int i){
		  while(!bShouldSub){
			  try {
				this.wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		  }
			for(int j=1;j<=10;j++){
				System.out.println("sub thread sequence of " + j + ",loop of " + i);
			}
		  bShouldSub = false;
		  this.notify();
	  }
	  
	  public synchronized void main(int i){
		  	while(bShouldSub){
		  		try {
					this.wait();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		  	}
			for(int j=1;j<=100;j++){
				System.out.println("main thread sequence of " + j + ",loop of " + i);
			}
			bShouldSub = true;
			this.notify();
	  }
  }

還是很少用到了wait()和notify()函式,但是它們是相對的,所以在實際運用中比較好把握。