1)wait()、notify()和notifyAll()方法是本地方法,並且為final方法,無法被重寫。
2)調用某個對象的wait()方法能讓當前線程阻塞,並且當前線程必須擁有此對象的monitor(即鎖)
3)調用某個對象的notify()方法能夠喚醒一個正在等待這個對象的monitor的線程,如果有多個線程都在等待這個對象的monitor,則只能喚醒其中一個線程;
4)調用notifyAll()方法能夠喚醒所有正在等待這個對象的monitor的線程;
有朋友可能會有疑問:為何這三個不是Thread類聲明中的方法,而是Object類中聲明的方法
(當然由於Thread類繼承了Object類,所以Thread也可以調用者三個方法)?其實這個問
題很簡單,由於每個對象都擁有monitor(即鎖),所以讓當前線程等待某個對象的鎖,當然
應該通過這個對象來操作了。而不是用當前線程來操作,因為當前線程可能會等待多個線程
的鎖,如果通過線程來操作,就非常復雜了。
上面已經提到,如果調用某個對象的wait()方法,當前線程必須擁有這個對象的monitor(即
鎖),因此調用wait()方法必須在同步塊或者同步方法中進行(synchronized塊或者
synchronized方法)。
調用某個對象的wait()方法,相當於讓當前線程交出此對象的monitor,然后進入等待狀態,
等待后續再次獲得此對象的鎖(Thread類中的sleep方法使當前線程暫停執行一段時間,從
而讓其他線程有機會繼續執行,但它並不釋放對象鎖);
notify()方法能夠喚醒一個正在等待該對象的monitor的線程,當有多個線程都在等待該對象
的monitor的話,則只能喚醒其中一個線程,具體喚醒哪個線程則不得而知。
同樣地,調用某個對象的notify()方法,當前線程也必須擁有這個對象的monitor,因此調用
notify()方法必須在同步塊或者同步方法中進行(synchronized塊或者synchronized方法)。
nofityAll()方法能夠喚醒所有正在等待該對象的monitor的線程,這一點與notify()方法是不同的。
Condition是在java 1.5中才出現的,它用來替代傳統的Object的wait()、notify()實現線程間的協作,相比使用Object的wait()、notify(),使用Condition1的await()、signal()這種方式實現線程間協作更加安全和高效。因此通常來說比較推薦使用Condition,在阻塞隊列那一篇博文中就講述到了,阻塞隊列實際上是使用了Condition來模擬線程間協作。
- Condition是個接口,基本的方法就是await()和signal()方法;
- Condition依賴於Lock接口,生成一個Condition的基本代碼是lock.newCondition()
- 調用Condition的await()和signal()方法,都必須在lock保護之內,就是說必須在lock.lock()和lock.unlock之間才可以使用Conditon中的await()對應Object的wait(); Condition中的signal()對應Object的notify(); Condition中的signalAll()對應Object的notifyAll()
---------------------------------
Object.wait/notify/notifyAll Condition.await/signal/signalAll