原文:http://www.java67.com/2012/08/what-are-difference-between-wait-and.html
Wait vs sleep
在Java多線程面試里面,經(jīng)常被問到wait() 和 sleep() 的區(qū)別。雖然 wait 和 sleep 都能將線程狀態(tài)變成等待狀態(tài),但是它們在行為和使用方式上完全不一樣的。Thread.sleep(long millis) 會暫停、釋放CPU資源和給其他線程有執(zhí)行的機會,而wait用于Java線程之間的通信。wait方法定義在java.lang.Object類里面,也就是說每個對象都能使用到。這是以對象鎖為基礎(chǔ)的,如果你記得在Java里面每一個對象都有隱藏鎖,也叫監(jiān)視器(monitor)。當一個線程進入一個synchronized方法的時候它會獲得一個當前對象的鎖,而當進入的是靜態(tài)(static)的synchronized方法的時候獲得的是這個類的鎖。使用wait()和notify()這兩個方法可以使得兩個線程之間進行通信,這也是解決很多多線程問題的關(guān)鍵,比如生產(chǎn)者-消費者問題,哲學家就餐問題,讀和寫的問題和實現(xiàn)一些并發(fā)的設(shè)計。
在這個教程,你會學到下列關(guān)于wait()和sleep()方法的問題:
1、什么是wait()方法?
2、什么是sleep()方法?
3、它們之間有什么區(qū)別?
4、在什么地方使用到wait和sleep?
話說,如果你是在準備面試Java的話我建議你還是看一下Java Programming Interview Exposed,一本非常不錯的Java面試書籍。
Java里面的wait和sleep方法是什么
wait方法定義在Object類里面,所有對象都能用到,在線程通信中,wait()方法經(jīng)常與notify()和notifyAll()方法一起使用。
當達到某種狀態(tài)的時候,wait()方法讓線程進入等待狀態(tài),比如生產(chǎn)者-消費者問題中,當隊列滿了的時候,生產(chǎn)者這時候需要等待,同樣,當隊列空的時候,消費者也需要等待。
notify()方法用于喚醒正在等待的線程,這個線程即將停止等待的狀態(tài),比如生產(chǎn)者線程往空隊列里面增加一個元素,此時notify方法會通知消費者線程這個隊列不再為空。另外,sleep()方法在Java應(yīng)用中用于暫停線程。
當一個線程不用做其他事了,你可以調(diào)用sleep方法將線程睡眠,它會在一定時間內(nèi)放棄當前的CPU資源。當一個線程已經(jīng)是睡眠狀態(tài)的時候一段時間后它會正常的喚醒,也可以通過線程中斷的特殊方式將它喚醒。
Java線程中wait和sleep方法的區(qū)別
在最后一部分中我們可以看到什么是wait()和sleep()和它們之間的區(qū)別。正如我之前所說,除了等待之外,它們是完全不同的:
1)第一個很重要的區(qū)別就是,wait方法必須正在同步環(huán)境下使用,比如synchronized方法或者同步代碼塊。如果你不在同步條件下使用,會拋出IllegalMonitorStateException異常。另外,sleep方法不需要再同步條件下調(diào)用,你可以任意正常的使用。
2)第二個區(qū)別是,wait方法用于和定義于Object類的,而sleep方法操作于當前線程,定義在java.lang.Thread類里面。
3)第三個區(qū)別是,調(diào)用wait()的時候方法會釋放當前持有的鎖,而sleep方法不會釋放任何鎖。
4)wait方法最好在循環(huán)里面調(diào)用,是為了處理錯誤的通告,比如說,即使線程喚醒了,等待狀態(tài)仍然適用。(看不懂?大概是循環(huán)里面再判斷一次線程是否真的醒來),然而sleep方法沒這樣的限制。最好別在循環(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)還有一個很大的區(qū)別是,一個是靜態(tài)方法,一個不是。
什么時候用wait和sleep方法?
從閱讀wait和sleep方法相關(guān)屬性和行為說明可以清楚的知道,wait()方法通常結(jié)合notify()或者notifyAll()方法在兩個線程通信中使用,而Thread.sleep()方法是個讓程序或者線程暫停的的工具方法。wait方法的調(diào)用需要同步環(huán)境這個必要條件才能進行,而sleep方法不需要。
完整的總結(jié)一下wait和sleep方法的區(qū)別和不同的使用場景。一般wait()和notify()方法使用于線程間的通信;sleep()方法用于暫停當前線程的執(zhí)行。同時要注意,wait()方法會釋放鎖,而sleep()方法會一直持有鎖(直到睡眠結(jié)束)。所以如果你的設(shè)計中線程等待需要釋放鎖的話使用wait方法和nofity方法,否則使用sleep()方法.
結(jié)尾
第一次翻譯文章,翻譯有點生硬,望見諒,也歡迎指出翻譯不妥之處。