教育行業(yè)A股IPO第一股(股票代碼 003032)

全國咨詢/投訴熱線:400-618-4000

Java線程的生命周期包括哪幾種狀態(tài)?

更新時間:2021年11月10日14時26分 來源:傳智教育 瀏覽次數(shù):

好口碑IT培訓(xùn)

在java中,任何對象都要有生命周期,線程也不例外,它也有自己的生命周期。當(dāng)Thread對象創(chuàng)建完成時,線程的生命周期便開始了,當(dāng)run()方法中代碼正常執(zhí)行完畢或者線程拋出一個未捕獲的異常(Exception)或者錯誤(Error)時,線程的生命周期便會結(jié)束。線程的整個生命周期可以分為5個階段,分別是新建狀態(tài)(New)、就緒狀態(tài)(Runnable)、運(yùn)行狀態(tài)(Running)、阻塞狀態(tài)(Blocked)和死亡狀態(tài)(Terminated),線程的不同狀態(tài)表名了線程當(dāng)前正在進(jìn)行的活動。在程序中,通過一些操作可以使線程在不同狀態(tài)之間轉(zhuǎn)換,如下圖:

線程狀態(tài)轉(zhuǎn)化

上圖中展示了線程各種狀態(tài)的轉(zhuǎn)換關(guān)系,箭頭表示可轉(zhuǎn)換的方向,其中,單箭頭表示狀態(tài)只能單向的轉(zhuǎn)換,例如,線程只能從新建狀態(tài)轉(zhuǎn)換到就緒狀態(tài),反之則不能;雙箭頭表示兩種狀態(tài)可以互相轉(zhuǎn)換,例如,就緒狀態(tài)和運(yùn)行狀態(tài)可以互相轉(zhuǎn)換。通過一張圖還不能完全描述清楚線程各狀態(tài)之間的區(qū)別,接下來針對線程生命周期中的五種狀態(tài)分別進(jìn)行詳細(xì)講解,具體如下。


1. 新建狀態(tài)(New)

創(chuàng)建一個線程對象后,該線程對象就處于新建狀態(tài),此時它不能運(yùn)行,與其他Java對象一樣,僅僅由Java虛擬機(jī)為其分配了內(nèi)存,沒有表現(xiàn)出任何線程的動態(tài)特征。


2. 就緒狀態(tài)(Runnable)

當(dāng)線程對象調(diào)用了start()方法后,該線程就進(jìn)入就緒狀態(tài)。處于就緒狀態(tài)的線程位于線程隊列中,此時它只是具備了運(yùn)行的條件,能否獲得CPU的使用權(quán)并開始運(yùn)行,還需要等待系統(tǒng)的調(diào)度。


3. 運(yùn)行狀態(tài)(Running)

如果處于就緒狀態(tài)的線程獲得了CPU的使用權(quán),并開始執(zhí)行run()方法中的線程執(zhí)行體,則該線程處于運(yùn)行狀態(tài)。一個線程啟動后,它可能不會一直處于運(yùn)行狀態(tài),當(dāng)運(yùn)行狀態(tài)的線程使用完系統(tǒng)分配的時間后,系統(tǒng)就會剝奪該線程占用的CPU資源,讓其他線程獲得執(zhí)行的機(jī)會。需要注意的是,只有處于就緒狀態(tài)的線程才可能轉(zhuǎn)換到運(yùn)行狀態(tài)。

4.阻塞狀態(tài)(Blocked)

一個正在執(zhí)行的線程在某些特殊情況下,如被人為掛起或執(zhí)行耗時的輸入/輸出操作時,會讓出CPU的使用權(quán)并暫時中止自己的執(zhí)行,進(jìn)人阻塞狀態(tài)。線程進(jìn)人阻塞狀態(tài)后,就不能進(jìn)入排隊隊列。只有當(dāng)引起阻塞的原因被消除后,線程才可以轉(zhuǎn)入就緒狀態(tài)。

下面就列舉一下線程由運(yùn)行狀態(tài)轉(zhuǎn)換成阻塞狀態(tài)的原因,以及如何從阻塞狀態(tài)轉(zhuǎn)換成就緒狀態(tài)。

·當(dāng)線程試圖獲取某個對象的同步鎖時,如里該銷被其他線程所持有,則當(dāng)前線程會進(jìn)入阻塞狀態(tài),如果想從阻塞狀態(tài)進(jìn)入就緒狀態(tài)就必須獲取到其他線程所持有的鎖。

·當(dāng)線程調(diào)用了一個阻塞式的I/O方法時,該線程就會進(jìn)入阻寒狀態(tài),如果想進(jìn)入就緒狀態(tài)就必須要等到這個阻塞的I/O方法返回。

·當(dāng)線程調(diào)用了某個對象的wait()方法時,也會使線程進(jìn)入阻塞狀態(tài),如果想進(jìn)入就緒狀態(tài)就需要使用notify()方法喚醒該線程。

·當(dāng)線程調(diào)用了Thread的sleep(long millis)方法時,也會使線程進(jìn)入阻塞狀態(tài),在這種情況下,只需等到線程睡眠的時間到了后,線程就會自動進(jìn)入就緒狀態(tài)。

·當(dāng)在一個線程中調(diào)用了另一個線程的join()方法時,會使當(dāng)前線程進(jìn)入阻塞狀態(tài),在這種情況下,需要等到新加入的線程運(yùn)行結(jié)束后才會結(jié)束阻塞狀態(tài),進(jìn)入就緒狀態(tài)。

需要注意的是,線程從阻塞狀態(tài)只能進(jìn)入就緒狀態(tài),而不能直接進(jìn)人運(yùn)行狀態(tài),也就是說,結(jié)束阻塞的線程需要重新進(jìn)入可運(yùn)行池中,等待系統(tǒng)的調(diào)度。


5.死亡狀態(tài)(Terminated)

如果線程調(diào)用stop()方法或nun()方法正常執(zhí)行完畢,或者線程拋出一個未捕獲的異常(Exception)錯誤(Error),線程就進(jìn)入死亡狀態(tài)。一旦進(jìn)入死亡狀態(tài),線程將不再擁有運(yùn)行的資格,也不能再轉(zhuǎn)換到其他狀態(tài)。



猜你喜歡

進(jìn)程和線程的區(qū)別和聯(lián)系是什么?

Java中的線程池有哪些?

java線程休眠的sleep方法詳細(xì)介紹

傳智教育Java培訓(xùn)課程

0 分享到:
和我們在線交談!