Object類中的wait()方法和notify()方法

【Object類中的wait()方法和notify()方法】oop

wait():
	public final void wait(long timeout) throws InterruptedException
	參數:等待的時間,可選,不填則默認爲0。
	說明:
		1>使線程主動釋放對象鎖,並進入等待狀態,直到它被其餘線程經過notify()或notifyAll喚醒或者超過指定的等待時間。
		2>在調用wait方法前,線程必須得到該對象的對象鎖,即:只能在同步方法或同步代碼塊中調用wait方法,若是當前線程不是鎖的持有者,將拋出一個IllegalMonitorStateException異常(是RuntimeException的子類,故不須要捕獲)。
		3>wait方法執行完成後,該線程當即釋放持有的對象鎖(注:不是等到退出synchronized代碼塊後才釋放)。
		4>this method should always be used in a loop:
		
			synchronized (obj) {
				// 不知足條件時等待。	
				while (condition does not hold) {	
					obj.wait();						// 注:通常會有其它的線程當條件知足後調用notify方法
				}		
				// 知足條件時執行execute方法。
				execute();					 		// 注:使用while循環保證了這行代碼始終是在知足條件下被執行的!	
			}
			
			舉例:
				階段1)A線程執行該代碼塊時,發現不知足條件condition,則A線程進入等待狀態,並釋放對象鎖,
				階段2)B線程執行某些代碼後,知足了條件condition,而後調用notify()方法並釋放了對象鎖,
				階段3)若是此時C線程得到了該對象鎖,並執行了某些代碼致使又不知足條件condition了,當C線程釋放該對象鎖後,
				階段4)A線程纔得到了該對象鎖,並執行wait()方法後面的代碼。若是不使用while循環,而是使用if語句來判斷(以下),則會致使execute()方法在不知足條件的狀況下被執行了!
					synchronized (obj) {
						if (condition does not hold) {	
							obj.wait();
						}
						execute();
					}
			解析:
				執行execute方法的狀況:
					1)執行代碼塊時,條件已知足,則不會調用wait方法,直接執行execute方法。
					2)執行代碼塊時,條件不知足,則調用wait方法,等到被喚醒後(注:被喚醒後條件可能發生變化),再去執行execute方法。
				使用while循環:保證了在調用wait方法前(階段1)和在被喚醒後(階段4)都去檢查條件是否知足,若是知足則執行excute方法,若是不知足則繼續等待。
				使用if語句:只保證了在調用wait方法前(階段1)去檢查條件是否知足,並無在線程被喚醒後去檢查是否知足條件。若是發生了階段3的狀況,則execute方法將在不知足條件的狀況下執行了。


notify():
	public final void notify()
	說明:
		1>隨機選擇一個在該對象上調用wait方法的線程,賦予其對象鎖,解除其阻塞狀態。
		2>在執行notify()方法後,當前線程不會立刻釋放該對象鎖,要等到執行notify()方法的線程退出synchronized方法或synchronized代碼塊後,當前線程纔會釋放鎖,此時wait狀態的線程才能夠獲取該對象鎖,並繼續執行synchronized代碼塊中wait()方法後面的代碼。
	
	
notifyAll():
	public final void notifyAll()
	說明:喚醒在該對象上調用wait方法等待的全部線程。
	

說明:wait()、notify()、notifyAll()這三個方法:
	1)在調用方法前,線程必須得到該對象的對象鎖,若是當前線程不是鎖的持有者,方法將拋出一個IllegalMonitorStateException異常(是RuntimeException的子類,故不須要捕獲)。
	2)只能在非靜態同步方法或非靜態同步代碼塊內調用,並且必須由鎖對象來調用方法:
		1>這3個方法都是非靜態方法,且這3個方法必須由鎖對象調用,因此咱們不能在靜態同步方法和靜態代碼塊中調用(靜態同步方法的鎖是類的Class鎖)。
		2>synchronized修飾的非靜態方法:由於this就是鎖對象,因此能夠在同步方法中調用這三個方法(能夠將this省略)。
		3>synchronized修飾的非靜態同步代碼塊:必須使用鎖對象來調用這三個方法。
	3)因爲wait,notify和notifyAll都是鎖級別的操做,而鎖屬於對象,故把他們定義在Object類中,而不是定義在Thread類中。
相關文章
相關標籤/搜索