Java中wait()和sleep()區(qū)別小結(jié)
在 Java 多線程編程中,wait()和 sleep()是兩個(gè)常用的線程控制方法,但它們?cè)诠ぷ髟?、使用?chǎng)景和效果上有顯著區(qū)別。以下是兩者的主要差異:
1. 所屬類與基本性質(zhì)
- ?sleep()??:是
Thread類的靜態(tài)方法,可以直接通過Thread.sleep()調(diào)用,用于讓當(dāng)前線程暫停執(zhí)行指定的時(shí)間。 - ?wait()??:是
Object類的實(shí)例方法,必須通過對(duì)象實(shí)例調(diào)用(如obj.wait()),主要用于線程間的通信與協(xié)調(diào)。
2. 鎖的行為差異(核心區(qū)別)
?sleep()??:
- ?不釋放鎖?:當(dāng)線程調(diào)用
sleep()時(shí),即使線程進(jìn)入休眠狀態(tài),它仍然持有已經(jīng)獲取的任何對(duì)象鎖。 - 其他線程無法獲取被休眠線程持有的鎖,導(dǎo)致同步代碼塊或方法無法被并發(fā)執(zhí)行。
- ?不釋放鎖?:當(dāng)線程調(diào)用
?wait()??:
- ?釋放鎖?:調(diào)用
wait()會(huì)使線程釋放當(dāng)前持有的對(duì)象鎖,并進(jìn)入該對(duì)象的等待池(waiting pool)。 - 其他線程可以獲取該對(duì)象的鎖并執(zhí)行同步代碼。
- ?釋放鎖?:調(diào)用
3. 使用場(chǎng)景
?sleep()??:
- 用于讓線程暫停執(zhí)行一段時(shí)間,不涉及線程間通信。
- 典型場(chǎng)景:模擬延遲、定時(shí)任務(wù)、控制執(zhí)行節(jié)奏等。
?wait()??:
- 用于線程間協(xié)作,通常與
notify()/notifyAll()配合使用。 - 典型場(chǎng)景:生產(chǎn)者-消費(fèi)者模式、線程交替執(zhí)行等需要條件等待的場(chǎng)景。
- 用于線程間協(xié)作,通常與
4. 喚醒機(jī)制
?sleep()??:
- 自動(dòng)喚醒:線程會(huì)在指定的時(shí)間結(jié)束后自動(dòng)恢復(fù)就緒狀態(tài)。
?wait()??:
- 需要被動(dòng)喚醒:必須由其他線程調(diào)用同一對(duì)象的
notify()或notifyAll()方法才能喚醒。 - 也支持帶超時(shí)的
wait(long timeout),超時(shí)后會(huì)自動(dòng)喚醒。
- 需要被動(dòng)喚醒:必須由其他線程調(diào)用同一對(duì)象的
5. 調(diào)用前提條件
?sleep()??:
- 可以在任何地方調(diào)用,不需要在同步代碼塊中。
?wait()??:
- ?必須在同步代碼塊或同步方法中調(diào)用?(即必須先獲取對(duì)象的監(jiān)視器鎖)。
- 否則會(huì)拋出
IllegalMonitorStateException異常。
6. 異常處理
兩者都會(huì)拋出 InterruptedException:
- 當(dāng)線程在休眠或等待期間被其他線程中斷時(shí)觸發(fā)。
- 都需要捕獲或聲明拋出該異常。
7. 線程狀態(tài)變化
?sleep()??:
- 使線程進(jìn)入 ?TIMED_WAITING?(帶超時(shí))或 ?WAITING?(無超時(shí))狀態(tài)。
?wait()??:
- 使線程進(jìn)入 ?WAITING?(無超時(shí))或 ?TIMED_WAITING?(帶超時(shí))狀態(tài),并釋放鎖。
代碼示例對(duì)比
sleep() 示例(不釋放鎖)
synchronized (lock) {
System.out.println("線程獲取鎖,開始sleep");
try {
Thread.sleep(2000); // 休眠2秒,不釋放lock鎖
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("線程sleep結(jié)束");
}
// 其他線程必須等待sleep結(jié)束后才能獲取鎖
wait() 示例(釋放鎖)
synchronized (lock) {
System.out.println("線程獲取鎖,開始wait");
try {
lock.wait(); // 釋放lock鎖,進(jìn)入等待隊(duì)列
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("線程被喚醒,重新獲取鎖");
}
// 其他線程可以在wait期間獲取lock鎖
總結(jié)對(duì)比表
| 特性 | sleep() | wait() |
|---|---|---|
| ?所屬類? | Thread類的靜態(tài)方法 | Object類的實(shí)例方法 |
| ?鎖釋放? | 不釋放鎖 | 釋放鎖 |
| ?使用場(chǎng)景? | 線程暫停執(zhí)行 | 線程間通信與協(xié)作 |
| ?喚醒方式? | 自動(dòng)喚醒(時(shí)間到) | 需 notify()/notifyAll()喚醒 |
| ?調(diào)用前提? | 無需同步環(huán)境 | 必須在 synchronized中調(diào)用 |
| ?異常? | InterruptedException | InterruptedException+ IllegalMonitorStateException |
| ?典型用途? | 定時(shí)、延遲 | 生產(chǎn)者-消費(fèi)者、條件等待 |
關(guān)鍵結(jié)論
- ?鎖行為?:
sleep()持有鎖不放,wait()釋放鎖——這是最本質(zhì)的區(qū)別。 - ?協(xié)作機(jī)制?:
wait()/notify()是 Java 多線程協(xié)作的基礎(chǔ)機(jī)制,而sleep()只是單純的線程暫停。 - ?使用規(guī)范?:誤用
wait()(如不在同步塊中調(diào)用)會(huì)導(dǎo)致運(yùn)行時(shí)異常,而sleep()的使用相對(duì)簡(jiǎn)單。
在實(shí)際開發(fā)中,應(yīng)根據(jù)是否需要線程間協(xié)作來選擇使用哪個(gè)方法:若只是需要延遲,用 sleep();若需要等待某個(gè)條件滿足(如資源就緒),則用 wait()。
到此這篇關(guān)于Java中wait()和sleep()區(qū)別小結(jié)的文章就介紹到這了,更多相關(guān)Java wait()和sleep()區(qū)別內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue結(jié)合Springboot實(shí)現(xiàn)用戶列表單頁面(前后端分離)
本文主要介紹了Vue結(jié)合Springboot實(shí)現(xiàn)用戶列表單頁面,可以實(shí)現(xiàn)簡(jiǎn)單的查詢,刪除,修改,和添加用戶信息功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-07-07
SpringBoot登錄認(rèn)證前后端實(shí)現(xiàn)方案:SpringBoot + Mybatis +&
本文展示如何在Spring生態(tài)系統(tǒng)中整合IOC/DI、MyBatis、MD5加密、Session/Cookie管理、JWT令牌和攔截器,以實(shí)現(xiàn)一個(gè)企業(yè)級(jí)的認(rèn)證方案,前端使用HTML/CSS/JavaScript/JQuery,后端使用SpringBoot+MyBatis+JWT,通過統(tǒng)一返回結(jié)果封裝和圖形驗(yàn)證碼,提高了API的可維護(hù)性和安全性2025-10-10
Spring boot中限制 Mybatis SQL日志的大字段輸出問題
文章介紹Springboot中MyBatis SQL日志因大字段輸出導(dǎo)致日志膨脹及JVM內(nèi)存問題,建議通過Logback或Log4j2自定義Converter/Filter實(shí)現(xiàn)參數(shù)截?cái)嗷蛎撁?或調(diào)整日志級(jí)別限制調(diào)試信息,本文給大家介紹Spring boot中限制Mybatis SQL日志的大字段輸出問題,感興趣的朋友一起看看吧2025-10-10
IntelliJ IDEA配置java環(huán)境及解決IDEA不能直接運(yùn)行單個(gè)JAVA文件的問題
這篇文章主要介紹了IntelliJ IDEA配置java環(huán)境及解決IDEA不能直接運(yùn)行單個(gè)JAVA文件的問題,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07
springboot + vue 實(shí)現(xiàn)遞歸生成多級(jí)菜單(實(shí)例代碼)
這篇文章主要介紹了springboot + vue 實(shí)現(xiàn)遞歸生成多級(jí)菜單,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-12-12

