首先告訴你網上說的5種狀態是誤導,java中的線程實際上有6種狀態。5種狀態的說法其實是早期進程的狀態。
早期進程的狀態:
這裡所謂“進程狀態”指早期的那種“單線程進程”的狀態。
對於現在普遍的“多線程進程”,顯然,談論“進程狀態”已經沒有意義,應該談論“進程下某個線程的狀態”或者直接說“線程狀態”。不過有時還是會把“進程狀態”和“線程狀態”混著去說。
有些系統把線程叫成“輕量級進程”(light-weight process),所以還是在談“進程狀態”。
有時則甚至既不叫“進程”,也不叫“線程”,它們叫“task”或者“job”。
與傳統的running狀態的區別
有人常覺得 Java 線程狀態中還少了個 running 狀態,這其實是把兩個不同層面的狀態混淆了。對 Java 線程狀態而言,不存在所謂的running 狀態,它的 runnable 狀態包含了 running 狀態。
我們可能會問,為何 JVM 中沒有去區分這兩種狀態呢?
現在的時分(time-sharing)多任務(multi-task)作業系統架構通常都是用所謂的“時間分區(time quantum or time slice)”方式進行搶佔式(preemptive)輪轉調度(round-robin式)。
這個時間分區通常是很小的,一個線程一次最多隻能在 cpu 上運行比如10-20ms 的時間(此時處於 running 狀態),也即大概只有0.01秒這一量級,時間片用後就要被切換下來放入調度隊列的末尾等待再次調度。(也即回到 ready 狀態)
通常,Java的線程狀態是服務於監控的,如果線程切換得是如此之快,那麼區分 ready 與 running 就沒什麼太大意義了。
現今主流的 JVM 實現都把 Java 線程一一映射到作業系統底層的線程上,把調度委託給了作業系統,我們在虛擬機器層面看到的狀態實質是對底層狀態的映射及封裝。JVM 本身沒有做什麼實質的調度,把底層的 ready 及 running 狀態映射上來也沒多大意義,因此,統一成為runnable 狀態是不錯的選擇。
下面是Thread.State源碼中的注釋中的話:
These states are virtual machine states which do not reflect any operating system thread states。
這些狀態是虛擬機器狀態,它不反映任何作業系統的線程狀態。
RUNABLE狀態的注釋:
A thread in the runnable state is executing in the Java virtual machine but it may be waiting for other resources from the operating system such as processor.
處於 runnable 狀態下的線程正在 JAVA 虛擬機器中執行,但它可能正在等待來自於作業系統的其它資源,比如處理器。
Java中的 RUNNABLE 狀態 實際上是包含了 Ready與Running的狀態的,所以你完全可以無視網上那些不準確的說法,這種問題的答案往往就在源碼與javadoc中。
6中狀態:
NEW(建立)
RUNNABLE(可啟動並執行)
BLOCKED(阻塞)
WAITING(無限等待)
TIMED_WAITING(限期等待)
TERMINATED(終止)
相關文章:
Java 執行個體 - 擷取線程狀態
Java線程中幾種狀態分享