14.3 線程狀態
線程會是以下六種狀態之一:
new
Runnable
Blocked(堵塞)
Waiting
Timed Waiting
Terminated
上述的每一種狀態都會在接下來的部分中提及。
要知道當前線程的狀態,可以調用getState方法
14.3.1 New Threads
當你創建一個線程伴隨着new指針的時候,例如:new Thread(r)線程還沒有運行。這就意味着它是在new的狀態。
當一個線程在new的狀態是,程序還沒開始運行它內部的代碼。確定數目的記錄需要被完成在這個線程可以運行之前(原話是: A certain amout of bookkeeping needs to be done before a thread can run, 這裏筆者不知道如何翻譯)。
14.3.2 Runnable Threads
一旦你調用了start方法,線程會進入runnable狀態。一個在runnable狀態的線程實際上也許不會運行。這取決於操作系統是否給予這個線程運行。(雖然java規格說明書裏面沒有區分這些不同的狀態。一個運行中的線程仍然是在runnable狀態。)
一旦線程已經運行,它實際上不需要保持持續運行。事實上,一個運行中的線程偶然中止讓其他的線程有機會去運行,這樣的情況甚至是被期待的。線程運行時間表的細節取決於設備上的操作系統所提供方案。搶佔式系統給每個runnable狀態的線程一段執行它的任務的時間,當時間完畢以後,操作系統會搶佔線程資源並給予其他線程運行的機會。當選擇一個下一個線程時,操作系統會考慮線程的優先權。
所有的現代臺式機和服務器操作系統都使用搶佔式調度,但是,小型的設備例如電話可能還是使用協同式調度。在這樣的設備中,一個線程只會在它調用yield方法,或者處於堵塞和等待狀態下失去對資源的控制權。
在一個有多處理器的機器上,每一個處理器都可以運行一個線程,因此我們可以並行運行多個線程,但是如果線程數目比處理器多,調度機還是會進行時間分片。
永遠記住,一個在runnable狀態的線程在任何時刻都不一定正在運行(這也是這個狀態叫runnable而不是running的原因)
14.3.3 Blocked and Waiting Threads
當一個線程是堵塞或者等待狀態是,它暫時你、不活躍。它不運行任何代碼,不消耗任何資源。它等待調度機去喚醒。具體細節決定於不活躍狀態是怎麼達到的。
當線程嘗試去獲取加了對象鎖的目前被其他線程使用着的資源時就會進入堵塞狀態。該線程在其他所有線程都解開該鎖並且調度機允許該線程去使用資源的時候,就會脫離堵塞狀態。
當線程等待另一個線程去通知調度器一個條件,它就進入了waiting狀態。這種情況可能發生在調用 Object.wait 或者 Thread.join 方法中,等待鎖的情況下。實際上,bocked和waiting狀態的差別並不重要。
少數的方法具有timeout參數。調動他們會導致線程進入timed waiting狀態。這個狀態直到時間終止或者適合的統治到達才結束。包括方法:Thread.sleep, object.wait, Thread.join, Lock.tryLock, Condition.await .
Figure , 14.3
14.3.4 終結狀態
線程被總結有以下兩個原因:
1. run方法退出,自然死亡
2. 一個沒有被捕獲的錯誤突然殺死run方法。
特別地,你可以殺死一個線程通過調用stop方法。該方法拋出ThreadDeath錯誤對象可以殺死線程。但是,反對使用該方法,你不應該在自己的代碼中使用該方法(難道應該在別人的代碼中使用???)
void join()
等待特別的線程終止
void join(long millis)
等待特定的線程死亡或者特定毫秒過去。
Thread.State getState()
得到此線程狀態,NEW,RUNNABLE,BLOCKED,WAITING,TIMED_WAITING, or TERMINATED之一
void stop()
停止線程,反對使用此方法
void suspend()
暫停線程的運行,反對使用此方法。
void resume()
從新獲取此線程,此方法只能在suspend方法使用後使用,反對使用此方法。