java中線程的sleep()方法和yield()方法的區(qū)別
1. sleep()方法
1.1 sleep()方法的定義
sleep()
方法是Thread
類的一個(gè)靜態(tài)方法,用于使當(dāng)前線程進(jìn)入休眠狀態(tài)(阻塞狀態(tài))一段指定的時(shí)間。在此期間,線程會(huì)暫停執(zhí)行并讓出CPU資源給其他線程。休眠時(shí)間結(jié)束后,線程會(huì)自動(dòng)從休眠狀態(tài)恢復(fù)到可運(yùn)行狀態(tài)(Runnable),等待操作系統(tǒng)重新調(diào)度。
sleep()
方法有兩個(gè)重載版本:
public static void sleep(long millis) throws InterruptedException; public static void sleep(long millis, int nanos) throws InterruptedException;
- 第一個(gè)方法使線程休眠指定的毫秒數(shù)。
- 第二個(gè)方法使線程休眠指定的毫秒數(shù)和額外的納秒數(shù)。
1.2 sleep()方法的工作原理
當(dāng)線程調(diào)用Thread.sleep()
時(shí),當(dāng)前線程會(huì)進(jìn)入阻塞狀態(tài),釋放CPU資源,其他線程可以利用這個(gè)時(shí)間片執(zhí)行。sleep()
方法不會(huì)釋放鎖或監(jiān)視器,即如果線程在同步塊或方法內(nèi)調(diào)用sleep()
,它仍然持有鎖。
sleep()
方法可以拋出InterruptedException
,這意味著如果線程在休眠期間被中斷,sleep()
會(huì)拋出此異常。因此,調(diào)用sleep()
時(shí)通常需要處理這個(gè)異常。
1.3 sleep()方法的應(yīng)用場景
- 限速操作:當(dāng)需要控制某些操作的執(zhí)行頻率時(shí),可以使用
sleep()
方法。例如,在游戲循環(huán)中控制幀率,或者在網(wǎng)絡(luò)請(qǐng)求中限制請(qǐng)求的發(fā)送頻率。 - 等待條件:在某些場景下,線程可能需要等待一段時(shí)間后再重新檢查某個(gè)條件,這時(shí)可以使用
sleep()
來實(shí)現(xiàn)。 - 模擬延遲:
sleep()
可以用于模擬任務(wù)的執(zhí)行延遲,以便在測(cè)試和調(diào)試中更好地模擬真實(shí)的執(zhí)行環(huán)境。
1.4 sleep()方法的示例
public class SleepExample { public static void main(String[] args) { Thread thread = new Thread(() -> { System.out.println("Thread is going to sleep..."); try { Thread.sleep(2000); // 線程休眠2秒 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Thread is awake!"); }); thread.start(); } }
在這個(gè)示例中,線程在啟動(dòng)后進(jìn)入休眠狀態(tài)2秒鐘,然后繼續(xù)執(zhí)行剩余的代碼。
2. yield()方法
2.1 yield()方法的定義
yield()
方法是Thread
類的另一個(gè)靜態(tài)方法,用于提示線程調(diào)度器當(dāng)前線程愿意讓出CPU資源,以便讓其他同優(yōu)先級(jí)或更高優(yōu)先級(jí)的線程獲得執(zhí)行機(jī)會(huì)。yield()
方法的調(diào)用并不保證當(dāng)前線程會(huì)立刻讓出CPU資源,也不保證其他線程會(huì)獲得執(zhí)行機(jī)會(huì),這完全取決于線程調(diào)度器的實(shí)現(xiàn)和當(dāng)前的系統(tǒng)負(fù)載。
public static native void yield();
2.2 yield()方法的工作原理
當(dāng)線程調(diào)用Thread.yield()
時(shí),線程調(diào)度器會(huì)檢查是否有其他同優(yōu)先級(jí)或更高優(yōu)先級(jí)的線程處于可運(yùn)行狀態(tài)(Runnable)。如果有,它們將獲得執(zhí)行機(jī)會(huì);如果沒有,當(dāng)前線程可能繼續(xù)運(yùn)行。因此,yield()
的作用類似于告訴調(diào)度器:“我現(xiàn)在已經(jīng)完成了一些工作,你可以選擇讓其他線程執(zhí)行。”
yield()
方法不會(huì)阻塞線程,線程僅僅是從“運(yùn)行狀態(tài)”(Running)進(jìn)入“可運(yùn)行狀態(tài)”(Runnable),以便讓其他線程有機(jī)會(huì)運(yùn)行。
2.3 yield()方法的應(yīng)用場景
- 調(diào)試和測(cè)試:在調(diào)試和測(cè)試多線程應(yīng)用程序時(shí),
yield()
可以幫助模擬和驗(yàn)證線程調(diào)度行為。 - 減輕競爭:在某些競爭條件較高的場景中,
yield()
可以用于提示線程調(diào)度器切換到其他線程,減輕線程之間的競爭。 - 協(xié)作式多任務(wù)處理:雖然現(xiàn)代操作系統(tǒng)多采用搶占式調(diào)度,但在某些情況下,
yield()
可以幫助實(shí)現(xiàn)一種類似協(xié)作式調(diào)度的效果,特別是在多線程計(jì)算密集型任務(wù)中。
2.4 yield()方法的示例
public class YieldExample { public static void main(String[] args) { Runnable task1 = () -> { for (int i = 0; i < 5; i++) { System.out.println("Task 1 - " + i); Thread.yield(); // 提示調(diào)度器讓出CPU } }; Runnable task2 = () -> { for (int i = 0; i < 5; i++) { System.out.println("Task 2 - " + i); Thread.yield(); // 提示調(diào)度器讓出CPU } }; Thread thread1 = new Thread(task1); Thread thread2 = new Thread(task2); thread1.start(); thread2.start(); } }
在這個(gè)示例中,兩個(gè)線程交替運(yùn)行,每個(gè)線程在完成一次循環(huán)后調(diào)用yield()
,提示調(diào)度器將CPU時(shí)間分配給其他線程。
3. sleep()和 yield()的區(qū)別
3.1 目的不同
sleep()
:sleep()
的主要目的是使線程進(jìn)入休眠狀態(tài)一段時(shí)間,從而暫停執(zhí)行并釋放CPU資源。在這段時(shí)間內(nèi),線程不參與競爭,也不消耗CPU資源,直到休眠時(shí)間結(jié)束或被中斷。yield()
:yield()
的目的是提示線程調(diào)度器當(dāng)前線程愿意讓出CPU資源,使其他同優(yōu)先級(jí)或更高優(yōu)先級(jí)的線程有機(jī)會(huì)執(zhí)行。yield()
并不保證當(dāng)前線程會(huì)被掛起,它只是表明當(dāng)前線程愿意短暫地讓出CPU時(shí)間片。
3.2 行為不同
sleep()
:sleep()
是明確的時(shí)間控制,線程在調(diào)用sleep()
后會(huì)休眠指定的時(shí)間。在這段時(shí)間內(nèi),線程不會(huì)執(zhí)行任何操作,并且該線程必須等待時(shí)間結(jié)束后才能繼續(xù)執(zhí)行。yield()
:yield()
沒有時(shí)間控制,它只是將當(dāng)前線程從“運(yùn)行狀態(tài)”切換到“可運(yùn)行狀態(tài)”。它并不一定會(huì)導(dǎo)致線程讓出CPU時(shí)間片,調(diào)度器可能讓當(dāng)前線程繼續(xù)運(yùn)行,也可能選擇其他線程。
3.3 對(duì)線程狀態(tài)的影響
sleep()
:調(diào)用sleep()
會(huì)使線程進(jìn)入“阻塞狀態(tài)”(Blocked),直到指定的時(shí)間到達(dá)或被中斷。yield()
:調(diào)用yield()
不會(huì)使線程進(jìn)入阻塞狀態(tài),線程仍然處于“可運(yùn)行狀態(tài)”(Runnable),只是在等待調(diào)度器的重新調(diào)度。
3.4 是否釋放鎖
sleep()
:sleep()
不會(huì)釋放線程持有的任何鎖,即使線程在同步塊內(nèi)調(diào)用sleep()
,鎖仍然會(huì)被持有,其他線程無法獲取該鎖。yield()
:yield()
也不會(huì)釋放鎖。線程在調(diào)用yield()
時(shí)仍然持有所有鎖,這意味著即使線程短暫讓出CPU,其他線程也無法進(jìn)入該線程所持有的同步塊。
3.5 拋出異常的情況
sleep()
:sleep()
可能會(huì)拋出InterruptedException
,如果線程在休眠期間被其他線程中斷,必須處理這個(gè)異常。yield()
:yield()
不會(huì)拋出InterruptedException
或任何其他異常。
3.6 實(shí)際使用效果
sleep()
:適用于需要明確暫停執(zhí)行的場景,如限速、等待條件等。sleep()
確保線程在指定的時(shí)間內(nèi)不執(zhí)行任何任務(wù),并讓出CPU資源。yield()
:適用于想要讓調(diào)度器考慮切換到其他線程執(zhí)行的場景。yield()
的效果取決于線程調(diào)度器的實(shí)現(xiàn),不保證一定會(huì)切換到其他線程。
4. sleep()和 yield()的應(yīng)用場景總結(jié)
4.1 sleep()的應(yīng)用場景
- 實(shí)現(xiàn)定時(shí)任務(wù):在定時(shí)任務(wù)中,
sleep()
可以用來使線程等待指定時(shí)間,然后繼續(xù)執(zhí)行任務(wù)。 - 限速處理:在網(wǎng)絡(luò)請(qǐng)求、數(shù)據(jù)處理等場景中,
sleep()
可以用來控制執(zhí)行頻率,防止系統(tǒng)過載。 - 模擬延遲:在測(cè)試中,
sleep()
可以用來模擬任務(wù)
的延遲執(zhí)行,以便驗(yàn)證程序的行為。
4.2 yield()的應(yīng)用場景
- 調(diào)試和測(cè)試:
yield()
可以幫助調(diào)試多線程程序,檢查線程調(diào)度行為,尤其是在競爭條件較高的情況下。 - 減輕競爭:在高競爭場景中,
yield()
可以提示調(diào)度器切換到其他線程,從而減少資源競爭的激烈程度。 - 優(yōu)化并發(fā)性能:在某些計(jì)算密集型任務(wù)中,
yield()
可以幫助實(shí)現(xiàn)更公平的調(diào)度,避免某些線程長時(shí)間占用CPU。
5. 結(jié)束語
sleep()
和yield()
是Java多線程編程中的兩個(gè)重要方法,盡管它們都可以控制線程的執(zhí)行順序和時(shí)間,但它們的作用和應(yīng)用場景有顯著的區(qū)別。sleep()
用于明確的時(shí)間控制,讓線程進(jìn)入休眠狀態(tài),并讓出CPU資源;而yield()
用于提示調(diào)度器當(dāng)前線程愿意讓出CPU,但不保證會(huì)讓出。
在實(shí)際開發(fā)中,合理使用sleep()
和yield()
,可以有效地控制線程的執(zhí)行順序,優(yōu)化并發(fā)程序的性能,避免不必要的資源競爭。
到此這篇關(guān)于java中線程的sleep()方法和yield()方法的區(qū)別的文章就介紹到這了,更多相關(guān)java sleep()和yield()內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring動(dòng)態(tài)管理定時(shí)任務(wù)之ThreadPoolTaskScheduler解讀
這篇文章主要介紹了Spring動(dòng)態(tài)管理定時(shí)任務(wù)之ThreadPoolTaskScheduler解讀,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-12-12spring boot+mybatis搭建一個(gè)后端restfull服務(wù)的實(shí)例詳解
這篇文章主要介紹了spring boot+mybatis搭建一個(gè)后端restfull服務(wù),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-11-11如何設(shè)置Spring Boot測(cè)試時(shí)的日志級(jí)別
Spring Boot是由Pivotal團(tuán)隊(duì)提供的全新框架,其設(shè)計(jì)目的是用來簡化新Spring應(yīng)用的初始搭建以及開發(fā)過程。該框架使用了特定的方式來進(jìn)行配置,從而使開發(fā)人員不再需要定義樣板化的配置。下面我們來一起學(xué)習(xí)一下吧2019-06-06IDEA生成項(xiàng)目maven-tree依賴目錄樹結(jié)構(gòu)方式
這篇文章主要介紹了IDEA生成項(xiàng)目maven-tree依賴目錄樹結(jié)構(gòu)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12