從作業系統層面上,任何執行緒一般都具有五種狀態,即創建、就緒、運行、阻塞、終止。
(1) 新建狀態(NEW)
在程式中用建構方法建立一個新執行緒時,如new Thread(),該執行緒就是建立狀態,此時它已經有了相應的記憶體空間和其它資源,但是還沒有開始執行。
(2) 就緒狀態(READ)
啟動執行緒可以透過呼叫新執行緒物件的start()方法來實現。當執行緒啟動時,執行緒就進入就緒狀態(runnable)
執行緒已具備執行條件,但因尚未分配CPU,故進入執行緒佇列排隊等待CPU服務。一旦系統選擇一個待執行的線程對象,該對象就會從等待狀態轉換為執行狀態。系統挑選的動作稱為「CPU調度」。當執行緒取得了CPU後,便進入運行狀態並自動執行其自身的run方法。
(3) 運作狀態(RUNNING)
執行緒進入運作狀態是指當就緒狀態的執行緒被呼叫並佔用處理器資源時。此時,自動呼叫該執行緒物件的run()方法。
(4) 阻塞狀態( BLOCKED)
一個正在執行的執行緒在某些特殊情況下,如被人為掛起或需要執行耗時的輸入輸出操作時,將會讓出CPU並暫時中止自己的執行,進入堵塞狀態。
如果使用sleep()、suspend()、wait()等方法在執行狀態下,執行緒將會發生阻塞。阻塞時,執行緒不能進入排隊佇列,只能當造成阻塞的原因被消除後,執行緒轉入就緒狀態,重新到就緒佇列排隊等待,這時被CPU調度選取後會從原來停止的位置開始繼續執行。
記住:阻塞被消除後是回到就緒狀態,不是運作狀態。
(5) 死亡狀態(TERMINATED)
當執行緒呼叫stop()、destory()或run()並執行完畢後,該執行緒將處於結束狀態。處於死亡狀態的執行緒不具有繼續運行的能力。
Java中執行緒的生命週期分為6種狀態。 Thread類別有一個實例屬性和一個實例方法專門用來保存和取得執行緒的狀態。其中,用於保存執行緒Thread實例狀態的實例屬性為:
// 以整数的形式保存线程的状态 private volatile int threadStatus = 0; // 返回当前线程的状态,一个枚举类型值 public State getState() { return sun.misc.VM.toThreadState(threadStatus); }
Thread.State是一個內部枚舉類,定義了6個枚舉常數,分別代表Java執行緒的6種狀態,具體如下:
public enum State { // 新建状态 NEW, // 运行状态 RUNNABLE, /** * 阻塞状态 * Object.wait */ BLOCKED, /** * 等待状态 * Object.wait * Thread.join * LockSupport.park */ WAITING, /** * 限时等待状态 * Thread.sleep * Object.wait * Thread.join * LockSupport.parkUntil * LockSupport.parkNanos */ TIMED_WAITING, // 终止状态 TERMINATED; }
有4種是比較常見的狀態,它們是:NEW(新建)狀態、RUNNABLE(可執行)狀態、TERMINATED(終止)狀態、TIMED_WAITING(限時等待)狀態。
(1) NEW狀態
Java原始碼對NEW狀態的說明是:建立成功但是沒有呼叫start()方法啟動的Thread執行緒實例都處於NEW狀態。
當然,並不是Thread線程實例的start()方法一經調用,其狀態就從NEW狀態到RUNNABLE狀態,此時並不意味著線程立即獲取CPU時間片並且立即執行,中間需要一系列作業系統的內部操作。
(2) RUNNABLE狀態
當呼叫了Thread實例的start()方法後,下一步如果執行緒取得CPU時間片開始執行,JVM將異步呼叫執行緒的run()方法執行其業務代碼。那麼在run()方法被非同步呼叫之前,JVM做了哪些事情呢?當Java執行緒的Thread實例的start()方法被呼叫後,作業系統中的對應執行緒進入的並不是運行狀態,而是就緒狀態,而Java執行緒並沒有這個就緒狀態。作業系統中執行緒的就緒狀態是什麼狀態的呢? JVM的執行緒狀態與其幕後的作業系統執行緒狀態之間的轉換關係簡化後如圖:
一個作業系統執行緒如果處於就緒狀態,就表示「萬事俱備,只欠東風”,即該線程已經滿足執行條件,但是還不能執行。處於就緒狀態的執行緒需要等待系統的調度,一旦就緒狀態被系統選中,取得CPU時間片,執行緒就開始佔用CPU,開始執行緒的程式碼,此時執行緒的作業系統狀態發生了改變,進入了運行狀態。
當作業系統中運作狀態的執行緒用完CPU時間片後,它會回到就緒狀態,等待下一次CPU調度。就這樣,作業系統執行緒在就緒狀態和執行狀態之間被系統重複地調度,這種情況會一直持續,直到執行緒的程式碼邏輯執行完成或異常終止。這時執行緒的作業系統狀態又發生了改變,進入執行緒的最後狀態——TERMINATED狀態。
就緒狀態和運作狀態都是作業系統中的執行緒狀態。在Java語言中,並沒有細分這兩種狀態,而是將這兩種狀態合併成同一種狀態——RUNNABLE狀態。因此,在Thread.State枚舉類別中,沒有定義執行緒的就緒狀態和運作狀態,只是定義了RUNNABLE狀態。這就是Java執行緒狀態和作業系統中執行緒狀態不同的地方。
當Thread實例處於NEW狀態時,一旦呼叫start()方法,該執行緒將轉換為RUNNABLE狀態。儘管如此,執行緒的run()方法不一定會馬上被並發執行,需要在執行緒取得了CPU時間片之後才真正啟動並發執行。
(3) TERMINATED狀態
當處於RUNNABLE狀態的執行緒執行完run()方法後,它會進入終止狀態TERMINATED。當然,如果在run()方法執行過程中發生了運行時異常而沒有被捕獲,run()方法將被異常終止,線程也會變成TERMINATED狀態。
(4) TIMED_WAITING狀態
#執行緒處於一種特殊的等待狀態,確切地說,執行緒處於限時等待狀態。能讓執行緒處於限時等待狀態的操作大致有以下幾種:
Thread.sleep(int n):使得目前執行緒進入限時等待狀態,等待時間為n毫秒。
Object.wait():帶有時限的搶佔物件的monitor鎖定。
Thread.join():帶有時限的執行緒合併。
LockSupport.parkNanos():讓執行緒等待,時間以奈秒為單位。
LockSupport.parkUntil():讓執行緒等待,時間可以靈活設定。
以上是Java執行緒的五種狀態是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!