您好,登錄后才能下訂單哦!
本篇內容主要講解“如何理解Java線程生命周期”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“如何理解Java線程生命周期”吧!
如果要說 Java 線程的生命周期的話,那我覺得就要先說說操作系統的線程生命周期
因為 JVM 是跑在操作系統上面的嘛,所以是繞不過去的,而且可以說, Java 語言中的線程本質上就是操作系統的線程
聰明的你肯定也發現了,不管是操作系統,還是 Java 或者 C# 都有線程的概念。在它們之間,關于線程的生命周期這一部分,肯定是有相同之處的,否則的話,操作系統自己一套生命周期流程, Java 又有自己的一套, C# 又有自己的一套,而且相互之間還要能夠互相配合,這種成本想想就大的不行對吧
所以咱們就來看看,通用的線程生命周期都有啥
先直接上張圖(阿粉這次的圖,可還行?):
可以看到,主要有 new , ready , running , waiting , terminated 5 種狀態
其中:
new 只是說,這個線程被創建了,但是還不允許分配 CPU 執行。因為這個狀態只是說明你在編程語言層面被創建了,操作系統層面還沒有被創建,肯定就談不上分配 CPU 執行了
ready 這個狀態是說,在操作系統層面已經成功創建了,所以接下來就是等待分配 CPU 執行了。還記得那句經典的嘛?ready ?go !
running 的狀態,相信你就知道了,我都已經 ready 了,此時如果再給我分配一下 CPU 我是不是就可以 go 了?那不就是 running 狀態了嘛
waiting 狀態,就是線程在 running 狀態的時候,突然發現,哎,我需要進行一下 I/O 操作,或者需要等待某個事件發生(比如說需要某個條件變量),這個時候是不是就不能再繼續 happy 的 running 了。那咋辦?waiting 一下唄
那你都 waiting 了,占用的 CPU 資源是不是應該釋放掉?所以說, waiting 狀態的線程是永遠沒有機會獲得 CPU 使用權的
你是不是一聽「永遠沒有機會」這幾個字就給嚇壞了,我該不會永遠沒有機會執行了吧。放心吧,你不是在 waiting 嘛,等你 wait 的事件發生了,就可以繼續到 running 狀態
當整個線程執行完畢,或者出現異常的時候,就進入了 terminated 狀態,也就是線程的使命就完成啦,處于 terminated 狀態的線程不會再切換到其他狀態了
通用的線程生命周期以及它們之間是如何切換的,到這里,應該就比較清楚了
接下來咱們看看 Java 線程的生命周期,在這個基礎上是怎么做的優化,有什么區別
Java 線程的生命周期
咱們先來瞅瞅源碼定義的狀態(為了突出重點,我把注釋都去掉了):
public enum State { NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED; }
能夠清楚的看到,在源碼中定義了 6 種線程狀態,剛才的通用狀態有幾種來著?5 種對吧,現在是 6 種。
這 6 種是干啥的?剛才的 5 種狀態以及它們之間的切換我搞清楚了,這 6 種狀態它們之間又是怎么切換的呢?
別急,阿粉這么貼心,肯定也是畫好了一張圖的:
這 6 個狀態咱們也是分別來看:
NEW 到 RUNNABLE ,應該是挺容易理解的,就是 thread 調用了 start 方法
Java 剛創建出來的 Thread 對象就是 NEW 狀態,創建 Thread 對象主要有兩種方法,一種是繼承 Thread 對象,重寫 run() 方法,一種是實現 Runnable 接口,重寫 run() 方法,并將該實現類作為創建 Thread 對象的參數
但是還記得嘛, NEW 只是說,這個線程在編程語言層面創建了,在操作系統層面還沒有創建,那當然就不會被操作系統調度了對不對,就更談不上執行了
所以 Java 線程如果想要執行的話,就必須轉換到 RUNNABLE 狀態,也就是 thread 調用 start 方法
RUNNABLE 與 BLOCKED ,如果線程等待 synchronized 的隱式鎖時,就會從 RUNNABLE 狀態轉到 BLOCKED 狀態。因為 synchronized 修飾的方法/代碼塊同一時刻只允許一個線程執行,所以其他線程就只能等待了唄,當等待的線程獲得 synchronized 隱式鎖時,就會從 BLOCKED 狀態轉到 RUNNABLE 狀態
在這里有沒有個疑問?就是線程在 wait 一個條件發生時,在操作系統層面線程會轉到 waiting 狀態,那么在 JVM 層面呢?在 JVM 層面, Java 線程狀態是不會發生變化的。也就是這個時候 Java 線程的狀態依然是 RUNNABLE 狀態
RUNNABLE 與 WAITING 狀態轉換,我感覺圖已經說得很好了,在這里不再贅述
RUNNABLE 與 TIMED_WAITING 狀態轉換,我感覺圖已經說得很好了,在這里也不再贅述,仔細觀察下會發現, TIMED_WAITING 與 WAITING 相比,就是多了超時參數,畢竟 TIMED_WAITING 是有時限等待嘛
RUNNABLE 到 TERMINATED ,這個過程比較好理解,線程執行完 run() 方法之后,就自動到 TERMINATED 狀態了,當然了如果在執行 run() 方法過程中有異常拋出,也會導致線程終止
有時候我們可能需要強制中斷 run() 方法的執行,怎么辦呢?是使用 stop() 方法還是 interrupt() 方法呢?正確的姿勢是調用 interrupt() 方法
stop() 方法會真的殺死線程,不給線程一點兒喘息的機會,如果被殺死的線程持有 synchronized 隱式鎖,那就再也不會釋放掉這個鎖了,接下來的線程也就沒辦法獲得 synchronized 隱式鎖,是不是特別危險?同樣 suspend() 和 resume() 這兩個方法也是不建議使用
interrupt() 方法相比于 stop() 方法就溫柔很多,它只是通知線程后續的操作可以不用去執行了,線程可以選擇執行現在就不執行,當然也可以選擇再執行一段時間后再停止,或者我就不聽你的,非要執行完,都沒關系, interrupt() 只是通知一下你而已。就比如你要做火車去一個地方,突然通知你這個火車晚點了,你可以選擇無視這個通知繼續等待,或者選擇另外一趟高鐵,但是不管你做什么,和火車站都沒啥關系,它通知的責任盡到了
看到這里應該就比較清楚了吧
在 Java 線程生命周期中, RUNNABLE 狀態是將 ready 和 running 兩種狀態合并在了一起,而 BLOCKED , WAITING , TIMED_WAITING 這三種狀態其實就是 waiting 狀態,也就是線程要等待某些事件發生,才能繼續向下執行下去
到此,相信大家對“如何理解Java線程生命周期”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。