Java中wait()和sleep()區(qū)別小結(jié)
在 Java 多線程編程中,wait()和 sleep()是兩個常用的線程控制方法,但它們在工作原理、使用場景和效果上有顯著區(qū)別。以下是兩者的主要差異:
1. 所屬類與基本性質(zhì)
- ?sleep()??:是
Thread類的靜態(tài)方法,可以直接通過Thread.sleep()調(diào)用,用于讓當前線程暫停執(zhí)行指定的時間。 - ?wait()??:是
Object類的實例方法,必須通過對象實例調(diào)用(如obj.wait()),主要用于線程間的通信與協(xié)調(diào)。
2. 鎖的行為差異(核心區(qū)別)
?sleep()??:
- ?不釋放鎖?:當線程調(diào)用
sleep()時,即使線程進入休眠狀態(tài),它仍然持有已經(jīng)獲取的任何對象鎖。 - 其他線程無法獲取被休眠線程持有的鎖,導(dǎo)致同步代碼塊或方法無法被并發(fā)執(zhí)行。
- ?不釋放鎖?:當線程調(diào)用
?wait()??:
- ?釋放鎖?:調(diào)用
wait()會使線程釋放當前持有的對象鎖,并進入該對象的等待池(waiting pool)。 - 其他線程可以獲取該對象的鎖并執(zhí)行同步代碼。
- ?釋放鎖?:調(diào)用
3. 使用場景
?sleep()??:
- 用于讓線程暫停執(zhí)行一段時間,不涉及線程間通信。
- 典型場景:模擬延遲、定時任務(wù)、控制執(zhí)行節(jié)奏等。
?wait()??:
- 用于線程間協(xié)作,通常與
notify()/notifyAll()配合使用。 - 典型場景:生產(chǎn)者-消費者模式、線程交替執(zhí)行等需要條件等待的場景。
- 用于線程間協(xié)作,通常與
4. 喚醒機制
?sleep()??:
- 自動喚醒:線程會在指定的時間結(jié)束后自動恢復(fù)就緒狀態(tài)。
?wait()??:
- 需要被動喚醒:必須由其他線程調(diào)用同一對象的
notify()或notifyAll()方法才能喚醒。 - 也支持帶超時的
wait(long timeout),超時后會自動喚醒。
- 需要被動喚醒:必須由其他線程調(diào)用同一對象的
5. 調(diào)用前提條件
?sleep()??:
- 可以在任何地方調(diào)用,不需要在同步代碼塊中。
?wait()??:
- ?必須在同步代碼塊或同步方法中調(diào)用?(即必須先獲取對象的監(jiān)視器鎖)。
- 否則會拋出
IllegalMonitorStateException異常。
6. 異常處理
兩者都會拋出 InterruptedException:
- 當線程在休眠或等待期間被其他線程中斷時觸發(fā)。
- 都需要捕獲或聲明拋出該異常。
7. 線程狀態(tài)變化
?sleep()??:
- 使線程進入 ?TIMED_WAITING?(帶超時)或 ?WAITING?(無超時)狀態(tài)。
?wait()??:
- 使線程進入 ?WAITING?(無超時)或 ?TIMED_WAITING?(帶超時)狀態(tài),并釋放鎖。
代碼示例對比
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鎖,進入等待隊列
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("線程被喚醒,重新獲取鎖");
}
// 其他線程可以在wait期間獲取lock鎖
總結(jié)對比表
| 特性 | sleep() | wait() |
|---|---|---|
| ?所屬類? | Thread類的靜態(tài)方法 | Object類的實例方法 |
| ?鎖釋放? | 不釋放鎖 | 釋放鎖 |
| ?使用場景? | 線程暫停執(zhí)行 | 線程間通信與協(xié)作 |
| ?喚醒方式? | 自動喚醒(時間到) | 需 notify()/notifyAll()喚醒 |
| ?調(diào)用前提? | 無需同步環(huán)境 | 必須在 synchronized中調(diào)用 |
| ?異常? | InterruptedException | InterruptedException+ IllegalMonitorStateException |
| ?典型用途? | 定時、延遲 | 生產(chǎn)者-消費者、條件等待 |
關(guān)鍵結(jié)論
- ?鎖行為?:
sleep()持有鎖不放,wait()釋放鎖——這是最本質(zhì)的區(qū)別。 - ?協(xié)作機制?:
wait()/notify()是 Java 多線程協(xié)作的基礎(chǔ)機制,而sleep()只是單純的線程暫停。 - ?使用規(guī)范?:誤用
wait()(如不在同步塊中調(diào)用)會導(dǎo)致運行時異常,而sleep()的使用相對簡單。
在實際開發(fā)中,應(yīng)根據(jù)是否需要線程間協(xié)作來選擇使用哪個方法:若只是需要延遲,用 sleep();若需要等待某個條件滿足(如資源就緒),則用 wait()。
到此這篇關(guān)于Java中wait()和sleep()區(qū)別小結(jié)的文章就介紹到這了,更多相關(guān)Java wait()和sleep()區(qū)別內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解使用spring boot admin監(jiān)控spring cloud應(yīng)用程序
這篇文章主要介紹了詳解使用spring boot admin監(jiān)控spring cloud應(yīng)用程序,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-05-05
Java 微信公眾號開發(fā)相關(guān)總結(jié)
公眾號作為主流的自媒體平臺,有著不少人使用。這次以文本回復(fù)作為案例來講解Java相關(guān)的微信公眾號開發(fā)2021-05-05
Java實現(xiàn)發(fā)送手機短信語音驗證功能代碼實例
這篇文章主要介紹了Java實現(xiàn)發(fā)送手機短信語音驗證功能代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2019-09-09
springboot實現(xiàn)返回視圖而不是string的方法
這篇文章主要介紹了springboot實現(xiàn)返回視圖而不是string的方法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-01-01
SpringBoot項目獲取統(tǒng)一前綴配置及獲取非確定名稱配置方法
在SpringBoot項目中,使用@ConfigurationProperties注解可獲取統(tǒng)一前綴的配置,具體做法是創(chuàng)建配置類,使用prefix屬性指定配置的前綴,本文給大家介紹SpringBoot項目獲取統(tǒng)一前綴配置以及獲取非確定名稱配置方法,感興趣的朋友跟隨小編一起看看吧2024-09-09
idea 無法創(chuàng)建Scala class 選項的原因分析及解決辦法匯總
這篇文章主要介紹了idea 無法創(chuàng)建Scala class 選項的解決辦法匯總,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-09-09
基于Spring Boot DevTools實現(xiàn)開發(fā)過程優(yōu)化
這篇文章主要介紹了基于Spring Boot DevTools實現(xiàn)開發(fā)過程優(yōu)化,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-09-09

