這篇文章主要介紹“java線程有多少種狀態(tài)”,在日常操作中,相信很多人在java線程有多少種狀態(tài)問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”java線程有多少種狀態(tài)”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!
平順ssl適用于網(wǎng)站、小程序/APP、API接口等需要進行數(shù)據(jù)傳輸應(yīng)用場景,ssl證書未來市場廣闊!成為創(chuàng)新互聯(lián)的ssl證書銷售渠道,可以享受市場價格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:13518219792(備注:SSL證書合作)期待與您的合作!
人有生老病死。同樣的,線程有自己的生命周期。在 Java 中線程的生命周期中一共有 6 種狀態(tài):
New(新創(chuàng)建)
Runnable(可運行)
Blocked(被阻塞)
Waiting(等待)
Timed Waiting(計時等待)
Terminated(被終止)
查看 Thread 類的源碼時,內(nèi)部還定義了這樣一個枚舉類。這個枚舉類定義的就是線程的狀態(tài),源碼如下:
public enum State { NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED; }
PS:線程在任何時刻只可能處于以上 6 種的其中 1 種狀態(tài),我們可以調(diào)用 getState () 查看線程的狀態(tài)。
我們知道線程有 6 種狀態(tài)。然而,它是如何切換的呢?狗哥根據(jù)自己的理解做了一張圖,接下來將根據(jù)這張圖詳細了解下線程狀態(tài)的切換。
線程的 6 種狀態(tài)
先注意 NEW 狀態(tài):線程被 NEW 出來,但還沒調(diào)用 start 方法時,就處于這種狀態(tài)。一旦調(diào)用了 start 方法也就進入了 RUNNABLE 狀態(tài)。
處于 RUNNABLE 的線程,比較特殊。它還分兩種狀態(tài):Running 和 Ready。也就是說,Java 中處于 Runnable 狀態(tài)的線程有可能正在執(zhí)行,也有可能沒有正在執(zhí)行,正在等待被分配 CPU 資源。
因此,我們可以推斷出,一個處于 Runnable 狀態(tài)的線程,當(dāng)它運行到任務(wù)的一半時,執(zhí)行該線程的 CPU 被調(diào)度去做其他事情,則該線程暫時不運行。但是,它的狀態(tài)依然不變,還是 Runnable,因為它有可能隨時被調(diào)度回來繼續(xù)執(zhí)行任務(wù)。
也就是說:處于 Runnable 狀態(tài)的線程并不一定在運行。這點在面試中常問,小伙伴們要注意了。
再來看看最簡單的 Blocked 狀態(tài),從 Runnable 進入 Blocked 只有一種可能:就是進入 synchronized 關(guān)鍵字保護的代碼,但是沒有獲取到 monitor 鎖。
線程的 6 種狀態(tài)
再來,看圖的右側(cè),Blocked ----> Runnable 狀態(tài):當(dāng)處于 Blocked 狀態(tài)的線程獲取到鎖。
線程從 Runnable 進入 Waiting 狀態(tài),有三種可能性:
沒有設(shè)置 Timeout 參數(shù)的 Object.wait () 方法。
沒有設(shè)置 Timeout 參數(shù)的 Thread.join () 方法。
LockSupport.park () 方法。
上面我們知道,線程進入 Blocked 狀態(tài)只可能是:進入 synchronized 保護的代碼,但是沒獲取到 monitor 鎖。然而,Java 中還有很多鎖,比如:ReentrantLock。線程在獲取這種鎖時,沒有搶到就會進入 Waiting 狀態(tài),因為它本質(zhì)上是調(diào)用了 LockSupport.park () 方法。
同樣的,調(diào)用 Object.wait () 和 Thread.join () 也會讓線程進入等待狀態(tài)。
Blocked 與 Waiting 的區(qū)別是:Blocked 在等待其他線程釋放 monitor 鎖,而 Waiting 則是在等待某個條件,比如 join 的線程執(zhí)行完畢,或者是 notify ()/notifyAll ()。
線程的 6 種狀態(tài)
看 Waiting 右側(cè),Waiting ----> Runnable:1、當(dāng)執(zhí)行了 LockSupport.unpark (),2、join 的線程運行結(jié)束,3、被中斷
看 Waiting 右側(cè),Waiting ----> Blocked:我們看圖可以知道其他線程調(diào)用 notify () 或 notifyAll () 來喚醒處于 Waiting 的線程,它會直接進入 Blocked 狀態(tài)。這是為什么?
其他線程能調(diào)用 notify () 或 notifyAll () 試圖喚醒 Waiting 狀態(tài)線程,說明必須持有同一個 monitor 鎖,也就是說處于 Waiting 的線程被喚醒后并不能馬上搶到 monitor 鎖,所以它必須先進入 Blocked 狀態(tài)。而喚醒它的線程執(zhí)行完畢釋放鎖后,它能搶到鎖就從 Blocked 進入 Runnable 狀態(tài)。
這種狀態(tài)與 Waiting 狀態(tài)的區(qū)別在于:有沒有時間限制,Timed Waiting 會等待超時,由系統(tǒng)自動喚醒,或者在超時前被喚醒信號喚醒。
有以下 5 種情況會讓線程進入 Timed Waiting 狀態(tài):
設(shè)置 Timeout 參數(shù)的 Thread.sleep (time) 方法。
設(shè)置 Timeout 參數(shù)的 Object.wait (time) 方法。
設(shè)置 Timeout 參數(shù)的 Thread.join (time) 方法。
設(shè)置 Timeout 參數(shù)的 LockSupport.parkNanos (long nanos) 方法。
設(shè)置 Timeout 參數(shù)的 LockSupport.parkUntil (long deadline) 方法。
線程的 6 種狀態(tài)
看 Timed Waiting 右側(cè),Timed Waiting ----> Blocked:跟 Waiting 一樣,其他線程執(zhí)行 notify () 和 notifyAll (),當(dāng)前線程也是先進入 Blocked 狀態(tài),而后視鎖的獲取情況再決定是否進入 Runnable 狀態(tài)。
另外,Timed Waiting ----> Runnable :1、當(dāng)前線程的超時時間到了且能直接獲取到鎖,2、join 的線程運行結(jié)束,3、被中斷,4、調(diào)用了 LockSupport.unpark (),這幾種情況會直接恢復(fù)到 Runnable,而無需經(jīng)歷 Blocked 狀態(tài)。
最后一種,想要進入終止?fàn)顟B(tài)就比較簡單了,有三種情況:
任務(wù)執(zhí)行完畢,線程正常退出。
出現(xiàn)一個沒有捕獲的異常(比如直接調(diào)用 interrupt () 方法)。
到此,關(guān)于“java線程有多少種狀態(tài)”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>
標題名稱:java線程有多少種狀態(tài)
文章位置:http://weahome.cn/article/iijsoe.html