原文:http://www.java67.com/2012/08/what-are-difference-between-wait-and.html
Wait vs sleep
在Java多線程面試?yán)锩嫦罕辏?jīng)常被問(wèn)到wait() 和 sleep() 的區(qū)別沉眶。雖然 wait 和 sleep 都能將線程狀態(tài)變成等待狀態(tài)雁社,但是它們?cè)谛袨楹褪褂梅绞缴贤耆灰粯拥摹hread.sleep(long millis) 會(huì)暫停配喳、釋放CPU資源和給其他線程有執(zhí)行的機(jī)會(huì)赂韵,而wait用于Java線程之間的通信送淆。wait方法定義在java.lang.Object類(lèi)里面章鲤,也就是說(shuō)每個(gè)對(duì)象都能使用到摊灭。這是以對(duì)象鎖為基礎(chǔ)的,如果你記得在Java里面每一個(gè)對(duì)象都有隱藏鎖败徊,也叫監(jiān)視器(monitor)帚呼。當(dāng)一個(gè)線程進(jìn)入一個(gè)synchronized方法的時(shí)候它會(huì)獲得一個(gè)當(dāng)前對(duì)象的鎖,而當(dāng)進(jìn)入的是靜態(tài)(static)的synchronized方法的時(shí)候獲得的是這個(gè)類(lèi)的鎖皱蹦。使用wait()和notify()這兩個(gè)方法可以使得兩個(gè)線程之間進(jìn)行通信煤杀,這也是解決很多多線程問(wèn)題的關(guān)鍵,比如生產(chǎn)者-消費(fèi)者問(wèn)題沪哺,哲學(xué)家就餐問(wèn)題沈自,讀和寫(xiě)的問(wèn)題和實(shí)現(xiàn)一些并發(fā)的設(shè)計(jì)。
在這個(gè)教程辜妓,你會(huì)學(xué)到下列關(guān)于wait()和sleep()方法的問(wèn)題:
1枯途、什么是wait()方法?
2籍滴、什么是sleep()方法酪夷?
3、它們之間有什么區(qū)別异逐?
4捶索、在什么地方使用到wait和sleep?
話說(shuō)灰瞻,如果你是在準(zhǔn)備面試Java的話我建議你還是看一下Java Programming Interview Exposed腥例,一本非常不錯(cuò)的Java面試書(shū)籍。
Java里面的wait和sleep方法是什么
wait方法定義在Object類(lèi)里面酝润,所有對(duì)象都能用到驻呐,在線程通信中,wait()方法經(jīng)常與notify()和notifyAll()方法一起使用诚纸。
當(dāng)達(dá)到某種狀態(tài)的時(shí)候嘉熊,wait()方法讓線程進(jìn)入等待狀態(tài),比如生產(chǎn)者-消費(fèi)者問(wèn)題中疏咐,當(dāng)隊(duì)列滿了的時(shí)候纤掸,生產(chǎn)者這時(shí)候需要等待,同樣浑塞,當(dāng)隊(duì)列空的時(shí)候借跪,消費(fèi)者也需要等待。
notify()方法用于喚醒正在等待的線程酌壕,這個(gè)線程即將停止等待的狀態(tài)掏愁,比如生產(chǎn)者線程往空隊(duì)列里面增加一個(gè)元素歇由,此時(shí)notify方法會(huì)通知消費(fèi)者線程這個(gè)隊(duì)列不再為空。另外果港,sleep()方法在Java應(yīng)用中用于暫停線程沦泌。
當(dāng)一個(gè)線程不用做其他事了,你可以調(diào)用sleep方法將線程睡眠辛掠,它會(huì)在一定時(shí)間內(nèi)放棄當(dāng)前的CPU資源谢谦。當(dāng)一個(gè)線程已經(jīng)是睡眠狀態(tài)的時(shí)候一段時(shí)間后它會(huì)正常的喚醒,也可以通過(guò)線程中斷的特殊方式將它喚醒公浪。
Java線程中wait和sleep方法的區(qū)別
在最后一部分中我們可以看到什么是wait()和sleep()和它們之間的區(qū)別他宛。正如我之前所說(shuō),除了等待之外欠气,它們是完全不同的:
1)第一個(gè)很重要的區(qū)別就是厅各,wait方法必須正在同步環(huán)境下使用,比如synchronized方法或者同步代碼塊预柒。如果你不在同步條件下使用队塘,會(huì)拋出IllegalMonitorStateException異常。另外宜鸯,sleep方法不需要再同步條件下調(diào)用憔古,你可以任意正常的使用。
2)第二個(gè)區(qū)別是淋袖,wait方法用于和定義于Object類(lèi)的鸿市,而sleep方法操作于當(dāng)前線程,定義在java.lang.Thread類(lèi)里面即碗。
3)第三個(gè)區(qū)別是焰情,調(diào)用wait()的時(shí)候方法會(huì)釋放當(dāng)前持有的鎖,而sleep方法不會(huì)釋放任何鎖剥懒。
4)wait方法最好在循環(huán)里面調(diào)用内舟,是為了處理錯(cuò)誤的通告,比如說(shuō)初橘,即使線程喚醒了验游,等待狀態(tài)仍然適用。(看不懂保檐?大概是循環(huán)里面再判斷一次線程是否真的醒來(lái))耕蝉,然而sleep方法沒(méi)這樣的限制。最好別在循環(huán)里面調(diào)用sleep方法夜只。
下面是關(guān)于調(diào)用wait和sleep方法的代碼片段:
```
synchronized(monitor){
while(condition ==true){monitor.wait())//releases monitor lock
}
Thread.sleep(100);//puts current thread on Sleep
```
5)還有一個(gè)很大的區(qū)別是赔硫,一個(gè)是靜態(tài)方法,一個(gè)不是盐肃。
什么時(shí)候用wait和sleep方法?
從閱讀wait和sleep方法相關(guān)屬性和行為說(shuō)明可以清楚的知道爪膊,wait()方法通常結(jié)合notify()或者notifyAll()方法在兩個(gè)線程通信中使用,而Thread.sleep()方法是個(gè)讓程序或者線程暫停的的工具方法砸王。wait方法的調(diào)用需要同步環(huán)境這個(gè)必要條件才能進(jìn)行推盛,而sleep方法不需要。
完整的總結(jié)一下wait和sleep方法的區(qū)別和不同的使用場(chǎng)景谦铃。一般wait()和notify()方法使用于線程間的通信耘成;sleep()方法用于暫停當(dāng)前線程的執(zhí)行。同時(shí)要注意驹闰,wait()方法會(huì)釋放鎖瘪菌,而sleep()方法會(huì)一直持有鎖(直到睡眠結(jié)束)。所以如果你的設(shè)計(jì)中線程等待需要釋放鎖的話使用wait方法和nofity方法嘹朗,否則使用sleep()方法.
結(jié)尾
第一次翻譯文章师妙,翻譯有點(diǎn)生硬,望見(jiàn)諒屹培,也歡迎指出翻譯不妥之處默穴。