本篇內(nèi)容主要講解“如何理解Java線程生命周期”,感興趣的朋友不妨來看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“如何理解Java線程生命周期”吧!
網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)!專注于網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、小程序開發(fā)、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了焦作免費(fèi)建站歡迎大家使用!
如果要說 Java 線程的生命周期的話,那我覺得就要先說說操作系統(tǒng)的線程生命周期
因?yàn)?JVM 是跑在操作系統(tǒng)上面的嘛,所以是繞不過去的,而且可以說, Java 語言中的線程本質(zhì)上就是操作系統(tǒng)的線程
聰明的你肯定也發(fā)現(xiàn)了,不管是操作系統(tǒng),還是 Java 或者 C# 都有線程的概念。在它們之間,關(guān)于線程的生命周期這一部分,肯定是有相同之處的,否則的話,操作系統(tǒng)自己一套生命周期流程, Java 又有自己的一套, C# 又有自己的一套,而且相互之間還要能夠互相配合,這種成本想想就大的不行對(duì)吧
所以咱們就來看看,通用的線程生命周期都有啥
先直接上張圖(阿粉這次的圖,可還行?):
可以看到,主要有 new , ready , running , waiting , terminated 5 種狀態(tài)
其中:
new 只是說,這個(gè)線程被創(chuàng)建了,但是還不允許分配 CPU 執(zhí)行。因?yàn)檫@個(gè)狀態(tài)只是說明你在編程語言層面被創(chuàng)建了,操作系統(tǒng)層面還沒有被創(chuàng)建,肯定就談不上分配 CPU 執(zhí)行了
ready 這個(gè)狀態(tài)是說,在操作系統(tǒng)層面已經(jīng)成功創(chuàng)建了,所以接下來就是等待分配 CPU 執(zhí)行了。還記得那句經(jīng)典的嘛?ready ?go !
running 的狀態(tài),相信你就知道了,我都已經(jīng) ready 了,此時(shí)如果再給我分配一下 CPU 我是不是就可以 go 了?那不就是 running 狀態(tài)了嘛
waiting 狀態(tài),就是線程在 running 狀態(tài)的時(shí)候,突然發(fā)現(xiàn),哎,我需要進(jìn)行一下 I/O 操作,或者需要等待某個(gè)事件發(fā)生(比如說需要某個(gè)條件變量),這個(gè)時(shí)候是不是就不能再繼續(xù) happy 的 running 了。那咋辦?waiting 一下唄
那你都 waiting 了,占用的 CPU 資源是不是應(yīng)該釋放掉?所以說, waiting 狀態(tài)的線程是永遠(yuǎn)沒有機(jī)會(huì)獲得 CPU 使用權(quán)的
你是不是一聽「永遠(yuǎn)沒有機(jī)會(huì)」這幾個(gè)字就給嚇壞了,我該不會(huì)永遠(yuǎn)沒有機(jī)會(huì)執(zhí)行了吧。放心吧,你不是在 waiting 嘛,等你 wait 的事件發(fā)生了,就可以繼續(xù)到 running 狀態(tài)
當(dāng)整個(gè)線程執(zhí)行完畢,或者出現(xiàn)異常的時(shí)候,就進(jìn)入了 terminated 狀態(tài),也就是線程的使命就完成啦,處于 terminated 狀態(tài)的線程不會(huì)再切換到其他狀態(tài)了
通用的線程生命周期以及它們之間是如何切換的,到這里,應(yīng)該就比較清楚了
接下來咱們看看 Java 線程的生命周期,在這個(gè)基礎(chǔ)上是怎么做的優(yōu)化,有什么區(qū)別
Java 線程的生命周期
咱們先來瞅瞅源碼定義的狀態(tài)(為了突出重點(diǎn),我把注釋都去掉了):
public enum State { NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED; }
能夠清楚的看到,在源碼中定義了 6 種線程狀態(tài),剛才的通用狀態(tài)有幾種來著?5 種對(duì)吧,現(xiàn)在是 6 種。
這 6 種是干啥的?剛才的 5 種狀態(tài)以及它們之間的切換我搞清楚了,這 6 種狀態(tài)它們之間又是怎么切換的呢?
別急,阿粉這么貼心,肯定也是畫好了一張圖的:
這 6 個(gè)狀態(tài)咱們也是分別來看:
NEW 到 RUNNABLE ,應(yīng)該是挺容易理解的,就是 thread 調(diào)用了 start 方法
Java 剛創(chuàng)建出來的 Thread 對(duì)象就是 NEW 狀態(tài),創(chuàng)建 Thread 對(duì)象主要有兩種方法,一種是繼承 Thread 對(duì)象,重寫 run() 方法,一種是實(shí)現(xiàn) Runnable 接口,重寫 run() 方法,并將該實(shí)現(xiàn)類作為創(chuàng)建 Thread 對(duì)象的參數(shù)
但是還記得嘛, NEW 只是說,這個(gè)線程在編程語言層面創(chuàng)建了,在操作系統(tǒng)層面還沒有創(chuàng)建,那當(dāng)然就不會(huì)被操作系統(tǒng)調(diào)度了對(duì)不對(duì),就更談不上執(zhí)行了
所以 Java 線程如果想要執(zhí)行的話,就必須轉(zhuǎn)換到 RUNNABLE 狀態(tài),也就是 thread 調(diào)用 start 方法
RUNNABLE 與 BLOCKED ,如果線程等待 synchronized 的隱式鎖時(shí),就會(huì)從 RUNNABLE 狀態(tài)轉(zhuǎn)到 BLOCKED 狀態(tài)。因?yàn)? synchronized 修飾的方法/代碼塊同一時(shí)刻只允許一個(gè)線程執(zhí)行,所以其他線程就只能等待了唄,當(dāng)?shù)却木€程獲得 synchronized 隱式鎖時(shí),就會(huì)從 BLOCKED 狀態(tài)轉(zhuǎn)到 RUNNABLE 狀態(tài)
在這里有沒有個(gè)疑問?就是線程在 wait 一個(gè)條件發(fā)生時(shí),在操作系統(tǒng)層面線程會(huì)轉(zhuǎn)到 waiting 狀態(tài),那么在 JVM 層面呢?在 JVM 層面, Java 線程狀態(tài)是不會(huì)發(fā)生變化的。也就是這個(gè)時(shí)候 Java 線程的狀態(tài)依然是 RUNNABLE 狀態(tài)
RUNNABLE 與 WAITING 狀態(tài)轉(zhuǎn)換,我感覺圖已經(jīng)說得很好了,在這里不再贅述
RUNNABLE 與 TIMED_WAITING 狀態(tài)轉(zhuǎn)換,我感覺圖已經(jīng)說得很好了,在這里也不再贅述,仔細(xì)觀察下會(huì)發(fā)現(xiàn), TIMED_WAITING 與 WAITING 相比,就是多了超時(shí)參數(shù),畢竟 TIMED_WAITING 是有時(shí)限等待嘛
RUNNABLE 到 TERMINATED ,這個(gè)過程比較好理解,線程執(zhí)行完 run() 方法之后,就自動(dòng)到 TERMINATED 狀態(tài)了,當(dāng)然了如果在執(zhí)行 run() 方法過程中有異常拋出,也會(huì)導(dǎo)致線程終止
有時(shí)候我們可能需要強(qiáng)制中斷 run() 方法的執(zhí)行,怎么辦呢?是使用 stop() 方法還是 interrupt() 方法呢?正確的姿勢(shì)是調(diào)用 interrupt() 方法
stop() 方法會(huì)真的殺死線程,不給線程一點(diǎn)兒喘息的機(jī)會(huì),如果被殺死的線程持有 synchronized 隱式鎖,那就再也不會(huì)釋放掉這個(gè)鎖了,接下來的線程也就沒辦法獲得 synchronized 隱式鎖,是不是特別危險(xiǎn)?同樣 suspend() 和 resume() 這兩個(gè)方法也是不建議使用
interrupt() 方法相比于 stop() 方法就溫柔很多,它只是通知線程后續(xù)的操作可以不用去執(zhí)行了,線程可以選擇執(zhí)行現(xiàn)在就不執(zhí)行,當(dāng)然也可以選擇再執(zhí)行一段時(shí)間后再停止,或者我就不聽你的,非要執(zhí)行完,都沒關(guān)系, interrupt() 只是通知一下你而已。就比如你要做火車去一個(gè)地方,突然通知你這個(gè)火車晚點(diǎn)了,你可以選擇無視這個(gè)通知繼續(xù)等待,或者選擇另外一趟高鐵,但是不管你做什么,和火車站都沒啥關(guān)系,它通知的責(zé)任盡到了
看到這里應(yīng)該就比較清楚了吧
在 Java 線程生命周期中, RUNNABLE 狀態(tài)是將 ready 和 running 兩種狀態(tài)合并在了一起,而 BLOCKED , WAITING , TIMED_WAITING 這三種狀態(tài)其實(shí)就是 waiting 狀態(tài),也就是線程要等待某些事件發(fā)生,才能繼續(xù)向下執(zhí)行下去
到此,相信大家對(duì)“如何理解Java線程生命周期”有了更深的了解,不妨來實(shí)際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!
網(wǎng)站欄目:如何理解Java線程生命周期
本文URL:http://jinyejixie.com/article28/jjijcp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站制作、網(wǎng)站建設(shè)、用戶體驗(yàn)、網(wǎng)站設(shè)計(jì)、App設(shè)計(jì)、定制網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)