Java線程的新建和就緒狀態(tài)實例分析
本文實例講述了Java線程的新建和就緒狀態(tài)。分享給大家供大家參考,具體如下:
一 點(diǎn)睛
當(dāng)線程被創(chuàng)建啟動以后,它既不是一啟動就進(jìn)入執(zhí)行狀態(tài),也不是一直處于執(zhí)行狀態(tài),在線程的生命周期中,它要經(jīng)過新建、就緒、運(yùn)行、阻塞和死亡5種狀態(tài)。當(dāng)線程啟動后,它不可能一直霸占CPU獨(dú)自運(yùn)行,所以CPU需要在多個線程之間切換,于是線程狀態(tài)也會多次在運(yùn)行和就緒之間切換。
當(dāng)程序使用new關(guān)鍵字創(chuàng)建一個線程后,該線程就處于新建狀態(tài)。
當(dāng)線程對象調(diào)用start()方法之后,該線程就處于就緒狀態(tài),處于這個狀態(tài)的線程并沒有開始運(yùn)行,只是表示該線程可以運(yùn)行了。至于該線程何時開始運(yùn)行,取決于JVM里線程調(diào)度器的調(diào)度。
自動線程使用start()方法,而不是run()方法,永遠(yuǎn)不要調(diào)用線程對象的run()方法。否則系統(tǒng)把線程對象當(dāng)作一個普通對象,而run()方法也是一個普通方法,而不是線程執(zhí)行體。
二 代碼
public class InvokeRun extends Thread { private int i ; // 重寫run方法,run方法的方法體就是線程執(zhí)行體 public void run() { for ( ; i < 100 ; i++ ) { // 直接調(diào)用run方法時,Thread的this.getName返回的是該對象名字, // 而不是當(dāng)前線程的名字。 // 使用Thread.currentThread().getName()總是獲取當(dāng)前線程名字 System.out.println(Thread.currentThread().getName() + " " + i); // ① } } public static void main(String[] args) { for (int i = 0; i < 100; i++) { // 調(diào)用Thread的currentThread方法獲取當(dāng)前線程 System.out.println(Thread.currentThread().getName() + " " + i); if (i == 20) { // 直接調(diào)用線程對象的run方法, // 系統(tǒng)會把線程對象當(dāng)成普通對象,run方法當(dāng)成普通方法, // 所以下面兩行代碼并不會啟動兩條線程,而是依次執(zhí)行兩個run方法 new InvokeRun().run(); new InvokeRun().run(); } } } }
三 運(yùn)行
......
main 93
main 94
main 95
main 96
main 97
main 98
main 99
main 0
main 1
main 2
main 3
main 4
main 5
......
四 說明
上面程序創(chuàng)建對象后直接調(diào)用了線程對象的run()方法,程序的運(yùn)行結(jié)果是整個程序只有一個線程:主線程。
如果直接調(diào)用線程對象的run()方法,則run()方法里不能直接通過getName()方法來獲得當(dāng)前執(zhí)行線程的名字,而是需要使用Thread.currentThread()方法先獲得當(dāng)前線程,再調(diào)用線程對象的getName()方法來獲得線程的名字。
啟動線程的正確方法是調(diào)用Thread對象的start()方法,而不是直接調(diào)用run()方法,否則就會變成單線程程序。
調(diào)用了run()方法之后,該線程已經(jīng)不再處于新建狀態(tài),不要再次調(diào)用線程對象的start()方法。
只能對處于新建狀態(tài)的線程調(diào)用start()方法,否則會引發(fā)異常。
如果希望調(diào)用子線程的start()方法后子線程立即開始執(zhí)行,程序可以使用Thread.sleep(1)來讓當(dāng)前運(yùn)行的線程(主線程)睡眠1毫秒,因為1毫秒內(nèi)CPU不會空閑,它會去執(zhí)行另一個處于就緒狀態(tài)的線程,這樣就可以讓子線程立即開始執(zhí)行。
更多java相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Java進(jìn)程與線程操作技巧總結(jié)》、《Java數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Java操作DOM節(jié)點(diǎn)技巧總結(jié)》、《Java文件與目錄操作技巧匯總》和《Java緩存操作技巧匯總》
希望本文所述對大家java程序設(shè)計有所幫助。
相關(guān)文章
Java中Integer.valueOf,parsetInt() String.valueOf的區(qū)別和結(jié)果代碼解析
本文通過代碼給大家講解了JAVA中Integer.valueOf, parsetInt() String.valueOf的區(qū)別和結(jié)果,需要的朋友可以參考下2018-05-05SpringBoot整合第三方技術(shù)的實現(xiàn)
本文主要介紹了SpringBoot整合第三方技術(shù)的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-02-02Java ScheduledExecutorService的具體使用
ScheduledExecutorService有線程池的特性,也可以實現(xiàn)任務(wù)循環(huán)執(zhí)行,本文主要介紹了Java ScheduledExecutorService的具體使用,具有一定的參考價值,感興趣的可以了解一下2023-05-05SpringBoot實現(xiàn)指標(biāo)監(jiān)控
這篇文章主要介紹了SpringBoot實現(xiàn)指標(biāo)監(jiān)控方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-05-05SpringBoot整合Redis、ApachSolr和SpringSession的示例
本篇文章主要介紹了SpringBoot整合Redis、ApachSolr和SpringSession的示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-02-02Java if(boolean)和if(boolean=true)區(qū)別解析
這篇文章主要介紹了Java if(boolean)和if(boolean=true)區(qū)別解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-02-02Java實現(xiàn)讀取163郵箱,qq郵箱的郵件內(nèi)容
這篇文章主要利用Java語言實現(xiàn)讀取163郵箱和qq郵箱的郵件內(nèi)容,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起動手試一試2022-02-02springboot web項目打jar或者war包并運(yùn)行的實現(xiàn)
這篇文章主要介紹了springboot web項目打jar或者war包并運(yùn)行的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11Java中保留兩位小數(shù)的四種方法實現(xiàn)實例
今天小編就為大家分享一篇關(guān)于Java中保留兩位小數(shù)的四種方法實現(xiàn)實例,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2019-02-02