面試官:您知道線程的生命周期包括哪幾個階段?
應聘者:
線程的生命周期包含5個階段,包括:新建、就緒、運行、阻塞、銷毀。
-
新建:就是剛使用new方法,new出來的線程;
-
就緒:就是調用的線程的start()方法后,這時候線程處於等待CPU分配資源階段,誰先搶的CPU資源,誰開始執行;
-
運行:當就緒的線程被調度並獲得CPU資源時,便進入運行狀態,run方法定義了線程的操作和功能;
-
阻塞:在運行狀態的時候,可能因為某些原因導致運行狀態的線程變成了阻塞狀態,比如sleep()、wait()之后線程就處於了阻塞狀態,這個時候需要其他機制將處於阻塞狀態的線程喚醒,比如調用notify或者notifyAll()方法。喚醒的線程不會立刻執行run方法,它們要再次等待CPU分配資源進入運行狀態;
-
銷毀:如果線程正常執行完畢后或線程被提前強制性的終止或出現異常導致結束,那么線程就要被銷毀,釋放資源;
完整的生命周期圖如下:
新建狀態
我們來看下面一段代碼:
Thread t1 = new Thread();
這里的創建,僅僅是在JAVA的這種編程語言層面被創建,而在操作系統層面,真正的線程還沒有被創建。只有當我們調用了 start() 方法之后,該線程才會被創建出來,進入Runnable狀態。只有當我們調用了 start() 方法之后,該線程才會被創建出來
就緒狀態
調用start()方法后,JVM 進程會去創建一個新的線程,而此線程不會馬上被 CPU 調度運行,進入Running狀態,這里會有一個中間狀態,就是Runnable狀態,你可以理解為等待被 CPU 調度的狀態
t1.start()
用一張圖表示如下:
那么處於Runnable狀態的線程能發生哪些狀態轉變?
Runnable狀態的線程無法直接進入Blocked狀態和Terminated狀態的。只有處在Running狀態的線程,換句話說,只有獲得CPU調度執行權的線程才有資格進入Blocked狀態和Terminated狀態,Runnable狀態的線程要么能被轉換成Running狀態,要么被意外終止。
運行狀態
當CPU調度發生,並從任務隊列中選中了某個Runnable線程時,該線程會進入Running執行狀態,並且開始調用run()方法中邏輯代碼。
那么處於Running狀態的線程能發生哪些狀態轉變?
-
被轉換成Terminated狀態,比如調用 stop() 方法;
-
被轉換成Blocked狀態,比如調用了sleep, wait 方法被加入 waitSet 中;
-
被轉換成Blocked狀態,如進行 IO 阻塞操作,如查詢數據庫進入阻塞狀態;
-
被轉換成Blocked狀態,比如獲取某個鎖的釋放,而被加入該鎖的阻塞隊列中;
-
該線程的時間片用完,CPU 再次調度,進入Runnable狀態;
-
線程主動調用 yield 方法,讓出 CPU 資源,進入Runnable狀態
阻塞狀態
Blocked狀態的線程能夠發生哪些狀態改變?
-
被轉換成Terminated狀態,比如調用 stop() 方法,或者是 JVM 意外 Crash;
-
被轉換成Runnable狀態,阻塞時間結束,比如讀取到了數據庫的數據后;
-
完成了指定時間的休眠,進入到Runnable狀態;
-
正在wait中的線程,被其他線程調用notify/notifyAll方法喚醒,進入到Runnable狀態;
-
線程獲取到了想要的鎖資源,進入Runnable狀態;
-
線程在阻塞狀態下被打斷,如其他線程調用了interrupt方法,進入到Runnable狀態;
終止狀態
一旦線程進入了Terminated狀態,就意味着這個線程生命的終結,哪些情況下,線程會進入到Terminated狀態呢?
-
線程正常運行結束,生命周期結束;
-
線程運行過程中出現意外錯誤;
-
JVM 異常結束,所有的線程生命周期均被結束。
作者:Java螞蟻
出處:https://www.cnblogs.com/marsitman/p/11228684.html
版權:轉載請在文章明顯位置注明作者及出處。