Java中wait和sleep方法的区别
1、兩者的區(qū)別
- 這兩個(gè)方法來(lái)自不同的類分別是Thread和Object ?
- 最主要是sleep方法沒有釋放鎖,而wait方法釋放了鎖,使得其他線程可以使用同步控制塊或者方法(鎖代碼塊和方法鎖)。 ?
- wait,notify和notifyAll只能在同步控制方法或者同步控制塊里面使用,而sleep可以在任何地方使用(使用范圍) ?
- sleep必須捕獲異常,而wait,notify和notifyAll不需要捕獲異常 ?
- sleep方法屬于Thread類中方法,表示讓一個(gè)線程進(jìn)入睡眠狀態(tài),等待一定的時(shí)間之后,自動(dòng)醒來(lái)進(jìn)入到可運(yùn)行狀態(tài),不會(huì)馬上進(jìn)入運(yùn)行狀態(tài),因?yàn)榫€程調(diào)度機(jī)制恢復(fù)線程的運(yùn)行也需要時(shí)間,一個(gè)線程對(duì)象調(diào)用了sleep方法之后,并不會(huì)釋放他所持有的所有對(duì)象鎖,所以也就不會(huì)影響其他進(jìn)程對(duì)象的運(yùn)行。但在sleep的過程中過程中有可能被其他對(duì)象調(diào)用它的interrupt(),產(chǎn)生InterruptedException異常,如果你的程序不捕獲這個(gè)異常,線程就會(huì)異常終止,進(jìn)入TERMINATED狀態(tài),如果你的程序捕獲了這個(gè)異常,那么程序就會(huì)繼續(xù)執(zhí)行catch語(yǔ)句塊(可能還有finally語(yǔ)句塊)以及以后的代碼。 ?
- 注意sleep()方法是一個(gè)靜態(tài)方法,也就是說(shuō)他只對(duì)當(dāng)前對(duì)象有效,通過t.sleep()讓t對(duì)象進(jìn)入sleep,這樣的做法是錯(cuò)誤的,它只會(huì)是使當(dāng)前線程被sleep?而不是t線程 ?
- ?wait屬于Object的成員方法,一旦一個(gè)對(duì)象調(diào)用了wait方法,必須要采用notify()和notifyAll()方法喚醒該進(jìn)程;如果線程擁有某個(gè)或某些對(duì)象的同步鎖,那么在調(diào)用了wait()后,這個(gè)線程就會(huì)釋放它持有的所有同步資源,而不限于這個(gè)被調(diào)用了wait()方法的對(duì)象。wait()方法也同樣會(huì)在wait的過程中有可能被其他對(duì)象調(diào)用interrupt()方法而產(chǎn)生 ?
?
如果線程A希望立即結(jié)束線程B,則可以對(duì)線程B對(duì)應(yīng)的Thread實(shí)例調(diào)用interrupt方法。如果此刻線程B正在wait/sleep/join,則線程B會(huì)立刻拋出InterruptedException,在catch() {} 中直接return即可安全地結(jié)束線程。
需要注意的是,InterruptedException是線程自己從內(nèi)部拋出的,并不是interrupt()方法拋出的。對(duì)某一線程調(diào)用interrupt()時(shí),如果該線程正在執(zhí)行普通的代碼,那么該線程根本就不會(huì)拋出InterruptedException。但是,一旦該線程進(jìn)入到wait()/sleep()/join()后,就會(huì)立刻拋出InterruptedException。
?
waite()和notify()因?yàn)闀?huì)對(duì)對(duì)象的“鎖標(biāo)志”進(jìn)行操作,所以它們必須在synchronized函數(shù)或synchronized block中進(jìn)行調(diào)用。如果在non-synchronized函數(shù)或non-synchronizedblock中進(jìn)行調(diào)用,雖然能編譯通過,但在運(yùn)行時(shí)會(huì)發(fā)生illegalMonitorStateException的異常。
?
補(bǔ)充兩個(gè)重要的方法:yield()和join()
yield方法??
暫停當(dāng)前正在執(zhí)行的線程對(duì)象。??
yield()方法是停止當(dāng)前線程,讓同等優(yōu)先權(quán)的線程或更高優(yōu)先級(jí)的線程有執(zhí)行的機(jī)會(huì)。如果沒有的話,那么yield()方法將不會(huì)起作用,并且由可執(zhí)行狀態(tài)后馬上又被執(zhí)行。???
join方法是用于在某一個(gè)線程的執(zhí)行過程中調(diào)用另一個(gè)線程執(zhí)行,等到被調(diào)用的線程執(zhí)行結(jié)束后,再繼續(xù)執(zhí)行當(dāng)前線程。如:t.join();//主要用于等待t線程運(yùn)行結(jié)束,若無(wú)此句,main則會(huì)執(zhí)行完畢,導(dǎo)致結(jié)果不可預(yù)測(cè)。??
?
說(shuō)一下為什么使用wait()方法時(shí),一般是需要while循環(huán)而不是if?
while(!執(zhí)行條件) {wait(); } ....if(!執(zhí)行條件) {wait(); } ....while會(huì)一直執(zhí)行循環(huán),直到條件滿足,執(zhí)行條件才會(huì)繼續(xù)往下執(zhí)行。if只會(huì)執(zhí)行一次判斷條件,不滿足就會(huì)等待。這樣就會(huì)出現(xiàn)問題。
我們知道用notify() 和notifyAll()可以喚醒線程,一般我們常用的是notifyAll(),因?yàn)閚otify(),只會(huì)隨機(jī)喚醒一個(gè)睡眠線程,并不一定是我們想要喚醒的線程。如果使用的是notifyAll(),喚醒所有的線程,那你怎么知道他想喚醒的是某個(gè)正在等待的wait()線程呢,如果用while()方法,就會(huì)再次判斷條件是不是成立,滿足執(zhí)行條件了,就會(huì)接著執(zhí)行,而if會(huì)直接喚醒wait()方法,繼續(xù)往下執(zhí)行,根本不管這個(gè)notifyAll()是不是想喚醒的是自己還是別人,可能此時(shí)if的條件根本沒成立。
舉個(gè)例子:
while去水果店買蘋果,沒有了,然后while就和水果店老板說(shuō),有水果的時(shí)候通知我,我先回去了。if也去水果店買蘋果,沒有了,然后if就和水果店老板說(shuō),有水果的時(shí)候通知我,我先回去了。過一段時(shí)間,水果店老板發(fā)短信告訴while和if,有水果了,while去一看,水果店只是進(jìn)了香蕉,并不是蘋果,所以不是想要的水果,于是回去繼續(xù)等水果店老板通知,而if根本就不看是不是自己想要的蘋果,直接就叫老板送10斤水果過來(lái),這樣會(huì)導(dǎo)致你得到錯(cuò)誤的結(jié)果。
?
參考文獻(xiàn):
Java中wait 和sleep 方法比較
JAVA—sleep()和wait()的區(qū)別
java中的sleep()和wait()的區(qū)別
轉(zhuǎn)載于:https://www.cnblogs.com/cyl048/p/8612453.html
總結(jié)
以上是生活随笔為你收集整理的Java中wait和sleep方法的区别的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 拼多多2018
- 下一篇: bzoj1935: [Shoi2007]