更新時間:2021-03-17 來源:黑馬程序員 瀏覽量:
在Java中,任何對象都有生命周期,線程也不例外,它也有自己的生命周期。當Thread對象創建完成時,線程的生命周期便開始了,當線程任務中代碼正常執行完畢或者線程拋出一個未捕獲的異常(Exception)或者錯誤(Error)時,線程的生命周期便會結束。
Java官方API將線程的整個生命周期分為六個狀態,分別是NEW(新建狀態)、RUNNABLE(可運行狀態)、BLOCKED(阻塞狀態)、WAITING(等待狀態)、TIMED_WAITING(定時等待狀態)和TERMINATED(終止狀態)。線程的不同狀態表明了線程當前正在進行的活動,在程序中,通過一些操作,可以使線程在不同狀態之間轉換,如圖1所示。
圖1 線程狀態轉換圖
圖1中展示了線程各種狀態的轉換關系,箭頭方向表示可轉換的方向。接下來,針對線程生命周期中的六種狀態分別進行詳細講解,具體如下:
1.NEW(新建狀態)
創建一個線程對象后,該線程對象就處于新建狀態,此時它不能運行,和其他Java對象一樣,僅僅由JVM為其分配了內存,沒有表現出任何線程的動態特征。
2.RUNNABLE(可運行狀態)
當新建狀態下的線程對象調用了start()方法,此時就會從新建狀態進入可運行狀態。從圖10-10可以看出,在RUNNABLE狀態內部又可細分成兩種狀態:READY(就緒狀態)和RUNNING(運行狀態),并且線程可以在這兩個狀態之間相互轉換。
● 就緒狀態:線程對象調用start()方法之后,等待JVM的調度,此時線程并沒有運行;
● 運行狀態:線程對象獲得JVM調度,如果存在多個CPU,那么允許多個線程并行運行。
3.BLOCKED(阻塞狀態)
處于運行狀態的線程可能會因為某些原因失去CPU的執行權,暫時停止運行進入阻塞狀態。此時,JVM不會給線程分配CPU,直到線程重新進入就緒狀態,才有機會轉換到運行狀態。阻塞狀態的線程只能先進入就緒狀態,不能直接進入運行狀態。
線程一般會在以下兩種情況下進入阻塞狀態:
● 當線程A運行過程中,試圖獲取同步鎖時,卻被線程B獲取,此時JVM把當前線程A存到對象的鎖池中,線程A就會進入阻塞狀態;
● 當線程運行過程中,發出IO請求時,此時該線程也會進入阻塞狀態。
4.WAITING(等待狀態)
當處于運行狀態的線程調用了無時間參數限制的方法后,如wait()、join()等方法,就會將當前運行中的線程轉換為等待狀態。
處于等待狀態中的線程不能立即爭奪CPU使用權,必須等待其他線程執行特定的操作后,才有機會再次爭奪CPU使用權,將等待狀態的線程轉換為運行狀態。例如,調用wait()方法而處于等待狀態中的線程,必須等待其他線程調用notify()或者notifyAll()方法喚醒當前等待中的線程;調用join()方法而處于等待狀態中的線程,必須等待其他加入的線程終止。
5.TIMED_WAITING(定時等待狀態)
將運行狀態中的線程轉換為定時等待狀態中的線程與轉換為等待狀態中的線程操作類似,只是運行線程調用了有時間參數限制的方法,如sleep(long millis)、wait(long timeout)、join(long millis)等方法。
處于定時等待狀態中的線程也不能立即爭奪CPU使用權,必須等待其他相關線程執行完特定的操作或者限時時間結束后,才有機會再次爭奪CPU使用權,將定時等待狀態的線程轉換為運行狀態。例如,調用了wait(long timeout) 方法而處于等待狀態中的線程,需要通過其他線程調用notify()或者notifyAll()方法喚醒當前等待中的線程,或者等待限時時間結束后也可以進行狀態轉換。
6.TERMINATED(終止狀態)
線程的run()方法、call()方法正常執行完畢或者線程拋出一個未捕獲的異常(Exception)、錯誤(Error),線程就進入終止狀態。一旦進入終止狀態,線程將不再擁有運行的資格,也不能再轉換到其他狀態,生命周期結束。
猜你喜歡:
cookie和session的區別和用法【Java面試題解析】