Java線程的生命周期可以分為五個狀態,分別是新建(New)、就緒(Runnable)、運行(Running)、阻塞(Blocked)和終止(Terminated)。
線程狀態的轉換如下:
新建(New)狀態
在新建線程對象后,該線程對象還沒有被分配 CPU 時間片,不會執行任何代碼。此時線程對象處于 New 狀態。
線程對象處于 New 狀態時,它的狀態可以改變,例如可以調用 start() 方法啟動線程,使其進入就緒狀態,也可以在新建線程對象時通過調用 setPriority() 方法設置線程的優先級,或者通過調用 setName() 方法設置線程的名稱等等。
就緒(Runnable)狀態
當線程調用了 start() 方法后,線程對象進入就緒狀態,此時它已經分配了 CPU 時間片,并等待系統分配 CPU 時間片開始執行線程代碼。處于就緒狀態的線程不一定能立即得到 CPU 時間片,它們處于等待狀態,直到系統分配到它們所需要的 CPU 時間片。
處于就緒狀態的線程通過調度器來決定哪個線程獲得 CPU 時間片,線程調度器的調度算法通常是先進先出(FIFO)。
運行(Running)狀態
當線程獲得了 CPU 時間片后,進入運行狀態,此時線程開始真正執行線程代碼。線程代碼中的指令依次執行,直到程序執行完畢或者執行到 sleep()、wait() 等方法時,線程會進入阻塞狀態,直到阻塞條件被解除。
在運行狀態下,線程可以執行一些耗時操作,例如計算、循環等等。當線程被分配到的 CPU 時間片用完后,系統會將其轉為就緒狀態,等待下一次分配 CPU 時間片。
阻塞(Blocked)狀態
線程在運行時可能會遇到一些阻塞條件,例如等待 I/O、sleep 等操作。當線程執行這些操作時,線程會進入阻塞狀態,它會暫停執行并且釋放 CPU 時間片,直到阻塞條件被解除。
在阻塞狀態下,線程不能執行任何代碼,直到阻塞條件被解除時,線程才會轉為就緒狀態,等待系統分配 CPU 時間片。
終止(Terminated)狀態
線程可能因為兩個原因進入終止狀態:(1)線程正常執行完畢,或者(2)線程出現了未捕獲的異常而意外終止。
線程進入終止狀態后,它會釋放所有的資源,并且不能再運行任何代碼。一旦線程進入了終止狀態,就不可能再回到運行狀態或阻塞狀態了。
例如,可以通過調用 Thread 類的 join() 方法,讓主線程等待子線程執行完畢后再終止,以保證線程能夠正常退出。