更新時(shí)間:2017-11-14 來(lái)源:黑馬程序員 瀏覽量:
任何對(duì)象都有生命周期,線程也不例外,它也有自己的生命周期。線程的整個(gè)生命周期分為六個(gè)階段,分別是新建狀態(tài)(New)、可運(yùn)行狀態(tài)(Runnable)、運(yùn)行狀態(tài)(Running)、阻塞狀態(tài)(Blocked)、等待狀態(tài)(Waiting)和死亡狀態(tài)(Terminated),線程的不同狀態(tài)表明了線程當(dāng)前正在進(jìn)行的活動(dòng)(有些地方把等待狀態(tài)分為兩種,加了一個(gè)定時(shí)等待Timed-Waiting)。
下面對(duì)線程生命周期中的六種狀態(tài)進(jìn)行詳細(xì)說(shuō)明。
1. 新建狀態(tài)(New)
創(chuàng)建一個(gè)線程對(duì)象后,該線程對(duì)象就處于新建狀態(tài),此時(shí)它不能運(yùn)行,和其它Java對(duì)象一樣,僅僅由Java虛擬機(jī)為其分配了內(nèi)存,沒有表現(xiàn)出任何線程的動(dòng)態(tài)特征。
2. 可運(yùn)行狀態(tài)(Runnable)
當(dāng)線程對(duì)象調(diào)用了start()方法后,該線程就進(jìn)入可運(yùn)行狀態(tài)。處于可運(yùn)行狀態(tài)的線程位于可運(yùn)行池中,此時(shí)它只是具備了運(yùn)行的條件,能否獲得CPU的使用權(quán)開始運(yùn)行,還需要等待系統(tǒng)的調(diào)度。
3. 運(yùn)行狀態(tài)(Running)
如果處于可運(yùn)行狀態(tài)的線程獲得了CPU的使用權(quán),開始執(zhí)行run()方法中的線程執(zhí)行體,則該線程處于運(yùn)行狀態(tài)。當(dāng)一個(gè)線程啟動(dòng)后,它不可能一直處于運(yùn)行狀態(tài)(除非它的線程執(zhí)行體足夠短,瞬間就結(jié)束了),系統(tǒng)會(huì)為每一個(gè)線程分配一小段的時(shí)間來(lái)處理任務(wù),當(dāng)線程用完了這段時(shí)間,系統(tǒng)就會(huì)剝奪該線程占用的CPU資源,讓其它線程獲得執(zhí)行的機(jī)會(huì)。需要注意的是,只有處于可運(yùn)行狀態(tài)的線程才可能轉(zhuǎn)換到運(yùn)行狀態(tài)。
4. 阻塞狀態(tài)(Blocked)和等待狀態(tài)(Waiting)
如果線程由于某些原因放棄了CPU的的使用權(quán),暫時(shí)停止運(yùn)行,此線程就進(jìn)入了阻塞或者等待狀態(tài),阻塞或者等待狀態(tài)都是由運(yùn)行狀態(tài)轉(zhuǎn)換而來(lái)的。下面列舉出線程進(jìn)入阻塞狀態(tài)或等待狀態(tài)的原因。
線程進(jìn)入阻塞的原因:
l 線程試圖獲取某個(gè)對(duì)象的同步鎖,而該鎖被其它線程持有
l 當(dāng)線程調(diào)用了一個(gè)阻塞式的IO方法
線程進(jìn)入等待狀態(tài)原因:
l 線程調(diào)用了某個(gè)對(duì)象的wait()方法
l 線程調(diào)用了Thread的sleep(longmillis)方法
l 線程調(diào)用了另一個(gè)線程的join()方法
當(dāng)正在執(zhí)行的線程進(jìn)入阻塞或者等待狀態(tài)后,其它處于可運(yùn)行狀態(tài)的線程就可以獲得執(zhí)行的機(jī)會(huì)。被阻塞或者等待的線程會(huì)在適當(dāng)?shù)臅r(shí)候重新進(jìn)入可運(yùn)行狀態(tài),等待系統(tǒng)的調(diào)度。下面列舉出線程由阻塞狀態(tài)或等待狀態(tài)進(jìn)入可運(yùn)行狀態(tài)的時(shí)機(jī)。
線程由阻塞狀態(tài)進(jìn)入可運(yùn)行狀態(tài)的時(shí)機(jī):
l 線程成功地獲取了某個(gè)對(duì)象的同步鎖
l 阻塞式的IO方法已經(jīng)返回
線程由等待狀態(tài)進(jìn)入可運(yùn)行狀態(tài)的時(shí)機(jī):
l 其它線程調(diào)用了某個(gè)對(duì)象的notify()或者notifyAll()方法
l Thread的sleep(longmillis)方法經(jīng)過(guò)了指定的時(shí)間
l 調(diào)用join()方法的線程執(zhí)行完畢
需要注意的是,線程從阻塞或者等待狀態(tài)只能進(jìn)入可運(yùn)行狀態(tài),而不能直接進(jìn)入運(yùn)行狀態(tài),也就是說(shuō),結(jié)束阻塞和等待的線程需要重新進(jìn)入可運(yùn)行池中,等待系統(tǒng)的調(diào)度。
5. 死亡狀態(tài)(Terminated)
線程的run()方法正常執(zhí)行完畢或者線程拋出一個(gè)未捕獲的異常(Exception)、錯(cuò)誤(Error),線程就進(jìn)入死亡狀態(tài)。一旦進(jìn)入死亡狀態(tài),線程將不再擁有運(yùn)行的資格,也不能再轉(zhuǎn)換到其它的狀態(tài)。
通過(guò)上面的講解,大家對(duì)線程的各種狀態(tài)以及狀態(tài)之間的轉(zhuǎn)換條件都有了詳細(xì)的了解,下面通過(guò)一張圖更清楚的描述這流中狀態(tài)的轉(zhuǎn)換關(guān)系:友情提示:獲得更多學(xué)科學(xué)習(xí)視頻+資料+源碼,請(qǐng)加QQ:3276250747。
本文版權(quán)歸黑馬程序員JavaEE學(xué)院所有,歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明作者出處。謝謝!
作者:黑馬程序員JavaEE培訓(xùn)學(xué)院
首發(fā):http://java.itheima.com/