[Java][Thread需要了解的那些事之生命周期]

1.線程生命周期

生命周期

2.按圖分析

當(dāng)線程通過new創(chuàng)建了一個(gè)Thread的時(shí)候,線程就處于New狀態(tài)。
1.當(dāng)這個(gè)Thread對(duì)象調(diào)用了start()方法的時(shí)候,這個(gè)線程就進(jìn)入到了Runable狀態(tài),也就是擁有了被執(zhí)行的資格,正在等待獲得CPU資源。
2.當(dāng)這個(gè)線程得到CPU資源,他就會(huì)進(jìn)入到Running狀態(tài),這時(shí)候會(huì)執(zhí)行Thread里的run()方法的任務(wù)。
3.當(dāng)這個(gè)線程執(zhí)行完run()方法的任務(wù)或者執(zhí)行過程中出現(xiàn)異常,那么線程就會(huì)進(jìn)入到Dead狀態(tài)。
4.當(dāng)這個(gè)線程調(diào)用了yield()的方法的時(shí)候,該線程就會(huì)進(jìn)入到Runnable狀態(tài)。繼續(xù)等待獲得CPU資源。
5.當(dāng)這個(gè)線程調(diào)用了sleep()或者I/O阻塞的時(shí)候,就會(huì)進(jìn)入到Blocked狀態(tài),當(dāng)睡眠時(shí)間過了,I/O完成了,線程就會(huì)進(jìn)入到Runnable狀態(tài)。
6.當(dāng)這個(gè)線程調(diào)用了join(),這個(gè)線程的父線程就會(huì)被阻塞,一般父線程的任務(wù)會(huì)在子線程的任務(wù)之前執(zhí)行。但如果子線程調(diào)用了join(),那么父線程就必須等待子線程任務(wù)完成或者超時(shí)(join可以設(shè)置超時(shí)時(shí)間),父線程會(huì)進(jìn)入到Runnable,等待獲得CPU資源才能進(jìn)行往下執(zhí)行。
7.這是在多線程同步的情況下討論的,當(dāng)一個(gè)線程獲得CPU資源后,也就是進(jìn)入到了Running狀態(tài),在run()方法里調(diào)用了wait(),那么這個(gè)線程就會(huì)進(jìn)入到等待Blocked狀態(tài)。當(dāng)其他線程調(diào)用了notify()或者notifyAll()的時(shí)候,這個(gè)線程就會(huì)進(jìn)入到鎖定Blocked狀態(tài),當(dāng)其他線程釋放了鎖之后,該線程就可以回到Runable狀態(tài)了。

3.過程解析

總的來說,線程的生命周期有五個(gè)過程。分別是new,runnable,running,blocked和dead.
(1) New
當(dāng)創(chuàng)建Thread類的一個(gè)實(shí)例(對(duì)象)時(shí),此線程進(jìn)入New狀態(tài)。例如:Thread thread=new Thread();處于New狀態(tài)的線程有自己的內(nèi)存空間。
(2) Runnable
當(dāng)新建的線程對(duì)象調(diào)用start()方法的時(shí)候,線程處于Runnable狀態(tài),這時(shí)候的線程已經(jīng)具備了運(yùn)行條件,但還沒有分配到CPU,處于線程就緒隊(duì)列(盡管是采用隊(duì)列形式,事實(shí)上,把它稱為可運(yùn)行池而不是可運(yùn)行隊(duì)列。因?yàn)閏pu的調(diào)度不一定是按照先進(jìn)先出的順序來調(diào)度的),等待系統(tǒng)為其分配CPU。Runnable狀態(tài)并不是執(zhí)行狀態(tài),當(dāng)系統(tǒng)選定一個(gè)處于Runnable狀態(tài)的Thread對(duì)象后,它就會(huì)從等待執(zhí)行狀態(tài)進(jìn)入執(zhí)行狀態(tài),系統(tǒng)挑選的動(dòng)作稱之為“cpu調(diào)度”。
(3) Running
處于Runnable狀態(tài)的線程一旦獲得CPU,線程就進(jìn)入Running狀態(tài)并自動(dòng)調(diào)用自己的run方法。處于Running狀態(tài)的線程最為復(fù)雜,它可以變?yōu)镽unnable狀態(tài)、Blocked狀態(tài)和Dead狀態(tài)。

當(dāng)對(duì)在Running狀態(tài)的線程調(diào)用yield()方法,它就會(huì)讓出CPU資源,再次變?yōu)榫途w狀態(tài),當(dāng)然,也會(huì)出現(xiàn)這種情況,線程調(diào)用yield()方法,這個(gè)線程進(jìn)入到Runnable狀態(tài),他和其他線程都有機(jī)會(huì)被重新分配CPU資源,這里就有可能出現(xiàn)該線程調(diào)用yield()方法讓出CPU資源后,處于Runnable狀態(tài)的該線程又被分配到了CPU資源,又可以重新進(jìn)入到Running狀態(tài)。

當(dāng)發(fā)生如下情況是,線程會(huì)從Running狀態(tài)變?yōu)锽locked狀態(tài):
① 線程調(diào)用sleep()方法主動(dòng)放棄所占用的系統(tǒng)資源
② 線程調(diào)用一個(gè)阻塞式IO方法,在該方法返回之前,該線程被阻塞
③ 線程試圖獲得一個(gè)同步監(jiān)視器(synchronized鎖),但同步監(jiān)視器正被其他線程所持有
④ 線程在等待某個(gè)通知(notify)
⑤ 程序調(diào)用了線程的suspend方法將線程掛起。不過該方法容易導(dǎo)致死鎖,所以程序應(yīng)該盡量避免使用該方法。這個(gè)方法已經(jīng)廢棄了。

當(dāng)線程的run()方法執(zhí)行完,或者被強(qiáng)制性地終止,例如出現(xiàn)異常,或者調(diào)用了stop()、destroy()方法等等,就會(huì)從Running狀態(tài)轉(zhuǎn)變?yōu)镈ead狀態(tài)。stop()和destroy()方法已經(jīng)廢棄了,建議不要再使用了。
(4) Blocked
處于Running狀態(tài)的線程在某些情況下,如執(zhí)行了sleep()方法或等待I/O設(shè)備等資源,將讓出CPU并暫時(shí)停止自己的運(yùn)行,進(jìn)入阻塞狀態(tài)。在阻塞狀態(tài)的線程不能進(jìn)入Runnale隊(duì)列。只有當(dāng)引起阻塞的原因消除時(shí),如睡眠時(shí)間已到,或等待的I/O設(shè)備空閑下來,線程便轉(zhuǎn)入Runnale狀態(tài),重新到Runnale隊(duì)列中排隊(duì)等待,被系統(tǒng)選中后進(jìn)入到Running狀態(tài),線程便從原來停止的位置開始繼續(xù)運(yùn)行。
(5) Dead
當(dāng)線程的run()方法執(zhí)行完,或者被強(qiáng)制性地終止,就認(rèn)為它死去。這個(gè)線程對(duì)象也許是活的,但是,它已經(jīng)不是一個(gè)單獨(dú)執(zhí)行的線程。線程一旦死亡,就不能復(fù)生。如果在一個(gè)死去的線程上調(diào)用start()方法,會(huì)拋出java.lang.IllegalThreadStateException異常。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 下面是我自己收集整理的Java線程相關(guān)的面試題,可以用它來好好準(zhǔn)備面試。 參考文檔:-《Java核心技術(shù) 卷一》-...
    阿呆變Geek閱讀 14,907評(píng)論 14 507
  • 本文主要講了java中多線程的使用方法、線程同步、線程數(shù)據(jù)傳遞、線程狀態(tài)及相應(yīng)的一些線程函數(shù)用法、概述等。 首先講...
    李欣陽閱讀 2,503評(píng)論 1 15
  • Java多線程學(xué)習(xí) [-] 一擴(kuò)展javalangThread類 二實(shí)現(xiàn)javalangRunnable接口 三T...
    影馳閱讀 2,987評(píng)論 1 18
  • 一、進(jìn)程和線程 進(jìn)程 進(jìn)程就是一個(gè)執(zhí)行中的程序?qū)嵗總€(gè)進(jìn)程都有自己獨(dú)立的一塊內(nèi)存空間,一個(gè)進(jìn)程中可以有多個(gè)線程。...
    阿敏其人閱讀 2,625評(píng)論 0 13
  • 前言 多線程并發(fā)編程是Java編程中重要的一塊內(nèi)容,也是面試重點(diǎn)覆蓋區(qū)域,所以學(xué)好多線程并發(fā)編程對(duì)我們來說極其重要...
    嘟爺MD閱讀 7,336評(píng)論 21 272