不從頭開始寫了。
線程狀態
- New(新生):當使用new操作符創建一個新的線程時,該線程還沒有運行(沒有調用
start
方法),這就意味着它的狀態是new。 - Runnable(可運行):一旦調用
start
方法,線程就處於可運行狀態,一個可運行的線程可能正在運行也可能沒有運行,這取決系統給線程提供的運行時間。一旦一個線程開始運行,它不必始終保持運行。 - Blocked(被阻塞)
- Waiting(等待)
- Timed waiting(計時等待)
:被阻塞線程和等待線程,它暫時不活動,不運行任何代碼且消耗最少的資源。直到線程調度器重新激活它。 - Terminated(被終止):線程因如下兩個原因之一而被終止:
- 因爲
run
方法正常退出而自然死亡 - 因爲一個沒有捕獲的異常終止了
run
方法而意外死亡
特別是,可以調用線程的stop
方法殺死一個線程。該方法拋出一個ThreadDeath
錯誤對象,由此殺死線程。但是stop
方法已過時,不要在自己的代碼中調用它。
- 因爲
中斷線程
當線程的
run
方法執行方法體中的最後一條語句,並經由return
語句返回時,或者出現了在方法中沒有捕獲的異常時,線程將終止。
有一種可以強制線程終止的方法:interrupt
:當對一個線程調用interrupt
方法時,線程的中斷狀態
將被置位。這是每個線程都具有的一個boolean
標誌位,每個線程都應該不時的檢查它,以判斷線程是否被中斷。方法如下:
先獲取到當前線程,然後調用isInterrupt
方法while(!Thread.currentThread.isInterript() && *maor work to do*) { do more work }
但是,如果線程被阻塞, ,就無法檢測中斷狀態,這是產生InterruptedException異常的地方,當在一個被阻塞的線程(wait或者sleep)上調用interrupt方法時,阻塞調用將會被InterruptedException異常中斷。一個被中斷的線程並不一定要終止,中斷一個線程不過是引起它的注意,被中斷的線程可以決定如何響應中斷,這種線程的run方法具有如下形式
public void run()
{
try
{
while( !Thread.currentThread().isInterrupted() && morework)
{
do more work
}
}
catch(InterruptedException e){
//thread was interrupted during sllep or wait
}
finally{
cleanup,if required
}
}
如果在中斷狀態被置位的情況下調用sleep,它不會休眠,相反,它將清除這已狀態並拋出InterruptedException異常。值得注意的是,線程裏面有幾個個非常相似的方法
+ boolean interrupted()
//靜態方法,檢測線程是否被中斷,調用該方法會清除該線程的中斷狀態
+ void interrupt()
//中斷當前線程
+ boolean isInterrupted()
//實例方法,檢測當前獻策和嗯是否被中斷,不會改變線程的中斷狀態
線程的屬性
- 線程優先級
在Java中,每一個線程有一個優先級。默認情況下,一個線程繼承它的父線程的優先級,可以用setPriority
方法提高或降低任何一個線程的優先級。可以將優先級設置爲MIN_PRIORITY(在Thread類中被定義爲1)
與MAX_PRIORITY(在Thread類中被定義爲10)
之間的任何值。
每當線程調度器有機會選擇新線程時,它首先選擇具有較高優先級的線程。但是線程優先級是高度依賴系統的。當Java的優先級被映射到到宿主機平臺的優先級上,優先級的個數也許更多,也許更少。 - 守護線程
可以通過調用t.SetDaemon(true)
將線程轉化爲守護線程。守護線程唯一的用途就是爲其他線程提供服務,當只剩下守護線程時,虛擬機就退出了,因爲只剩下守護線程,就沒有必要繼續運行程序了。守護線程應該永遠不要去訪問固有資源,如文件、數據庫等,因爲它會在任何時候甚至是一個操作的中間發生中斷。
未捕獲異常處理器
- 線程的run方法不能拋出任何被檢測的異常,但是不被檢測的異常會導致線程終止,在這種情況下,線程就死亡了。但是不需要任何catch字句來處理可以被傳播的異常,相反,在線程死亡之前異常被傳遞到一個用於處理未捕獲異常的處理器。該處理器必須屬於一個實現
Thread.UncaughtExceptionHandler
接口的類,這個接口只有一個方法:public void uncaughtException(Thread t, Throwable e)
。如果不安裝默認的處理器,默認的處理器爲空,但是,如果不爲獨立的線程安裝處理器,此時的處理器就是該線程的ThreadGroup對象。
ThreadGroup類實現Thread.UncaughtExceptionHandler
接口,它的uncaughtException
做了如下操作:
1) 如果該線程組有父線程組,那麼父線程組的uncaughtException
方法就會被調用
2) 否則,如果Thread.getDefaultUncaughtExceptionHandler()
返回一個非空處理器,則調用該處理器。
3) 否則,如果Throwable
是ThreadDeath
的一個實例,什麼都不做。
4) 否則,線程的名字以及Throwable
的棧蹤跡被輸出到System.err上。