關於Java的線程狀態

轉載 https://my.oschina.net/goldenshaw/blog/386788

Java線程有6種狀態。在某個給定時間點上,一個線程只能處於這6種狀態中的一種。

NEW (新建)       
一個尚未啓動的線程處於這一狀態。(A thread that has not yet started is in this state.)

RUNNABLE (可運行)       
一個正在 Java 虛擬機中執行的線程處於這一狀態。(A thread executing in the Java virtual machine is in this state.)
BLOCKED (阻塞)       
一個正在阻塞等待一個監視器鎖的線程處於這一狀態。(A thread that is blocked waiting for a monitor lock is in this state.)
WAITING (等待)       
一個正在無限期等待另一個線程執行一個特別的動作的線程處於這一狀態。(A thread that is waiting indefinitely for another thread to perform a particular action is in this state.)
TIMED_WAITING (計時等待)       
一個正在限時等待另一個線程執行一個動作的線程處於這一狀態。(A thread that is waiting for another thread to perform an action for up to a specified waiting time is in this state.)

TERMINATED (終止)       
一個已經退出的線程處於這一狀態。(A thread that has exited is in this state.)
JVM中則統一成了一種狀態,也可能操作系統中的一種狀態在JVM中又細分成了兩種狀態,誰知道呢?你也不想去知道,反正我是不想去知道。而很多關於操作系統上的書則常會提到有5種進程(process)狀態:new,ready,running,waiting,terminated。

不幸的是,有很多的書上常常把這些進程狀態,線程狀態與Java線程狀態混在一起談。這裏所謂“進程狀態”指早期的那種“單線程進程”的狀態。 對於現在普遍的“多線程進程”,顯然,談論“進程狀態”已經沒有意義,應該談論“進程下某個線程的狀態”或者直接說“線程狀態”。不過有時還是會把“進程狀態”和“線程狀態”混着去說。有些系統把線程叫成“輕量級進程”(light-weight process),所以還是在談“進程狀態”。有時則甚至既不叫“進程”,也不叫“線程”,它們叫“task”或者“job”。總之還是有些亂的,我們不妨就拿Windows系統爲例,用的就是“進程”和“線程”這兩種較爲標準的叫法,這時一個進程下至少有一個線程,線程是CPU調度的基本單位,進程不參與CPU調度,CPU根本不知道進程的存在。


    至於Java線程的狀態,有的說有4種狀態,有的說有5種,各種各樣的說法都有。比如看到Java只有RUNNABLE(可運行的)狀態,就覺得這還不夠呀,應該還有Running(運行中)狀態;又或者覺得RUNNABLE就是Running,所以應該還有個Ready(就緒)狀態纔對。然而這些說法都是不準確的!如果我們讀下Thread.State源碼中的註釋中,它說得很清楚:These states are virtual machine states which do not reflect any operating system thread states。這些狀態是虛擬機狀態,它不反映任何操作系統的線程狀態。一個 Java 線程它所對應的操作系統內核線程中的狀態可能有Running又有Ready,但在虛擬機層面則統一映射成了RUNNABLE。如果Java中覺得沒必要去區分這些,我們又何必去糾結這些呢?以RUNNABLE爲例,源碼中的註釋是這樣說的:executing in the Java virtual machine(正在Java虛擬機中執行)至於它是否真正在執行,不是我們要操心的事。還有的情況則比如把Java狀態中的BLOCKED,WAITING,TIMED_WAITING三種狀態都籠統地稱爲blocked或者waiting;操作系統也許只有一種狀態,但這一次,Java作了細分,給出了三種狀態。很多聲稱Java線程只有4種或5種狀態常常都是自作主張地合併了這些狀態,把這些東西混爲一談是非常容易引發混亂的。我們將會在後面具體地談到。又或者把TIMED_WAITING當作不存在,從來不提有這個狀態。顯然,這種做法又是受到傳統進程狀態劃分的影響。儘管它與WAITING很像,我們最好按着Thread.State中的定義來,不要自己隨意發揮。綜上所述,爲避免出現混亂,釐清概念所處的層次是非常重要的。如無特別說明,討論均在JVM層面上。具體而言,比如當說到WAITING狀態時,指的就是Thread.State.WAITING。

有了以上基礎,才能在接下來更好地去分析這6種狀態。

具體狀態分析
接下來再來細看這6個狀態,首先從簡單的談起。

NEW
當使用new Thread()創建一個新的線程,又還沒有開始執行(not yet started)它的時候就處於NEW狀態。這裏所謂“開始執行”具體指調用線程類中的start方法。注意:你不能直接調用run方法,這樣的話還是在原線程上執行。只有調用start方法纔會開啓新的執行線程,接着它會去調用run。在start之後,線程進入RUNNABLE狀態,之後還可能會繼續轉換成其它狀態。
注:一個線程只能被start一次。

TERMINATED
終止狀態,這個也沒什麼好說的,完成了執行後(completed execution)或者說退出了(exited)。線程就進入了終止狀態。
RUNNABLE:前面有提到,它指“正在Java虛擬機中執行”。


BLOCKED:等待監視器鎖(waiting for a monitor lock )這是一種特殊的waiting,實際上就是被synchronized方法或者塊阻塞。monitor有些書上通常叫”管程“,我也不太確定要怎麼叫它。這裏叫成”監視器“也是取字面的意思。


WAITING:無限期等待另一個線程執行一個特別的動作。(waiting indefinitely for another thread to perform a particular action )這裏所謂的動作通常即是指“notify或是notifyAll”。


TIMED_WAITING:限時等待另一個線程執行一個動作。(waiting for another thread to perform an action for up to a specified waiting time )如果沒有等到如“notify”之類的動作,時間到了也會自動退出這一狀態。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章