阿里一面:聊聊Java中執行緒的生命週期狀態

語言: CN / TW / HK

大家好,我是Tom哥。

面試時,你是否被問過這道題, “聊聊Java中執行緒的生命週期狀態吧!”

這幾乎是一道面試必答題,這道題怎麼答才是最佳答案呢?本文就帶大家 破解一下! 文末有技術書免費送~

0 1

一張圖說明執行緒生命週期

JVM原始碼中將執行緒的生命週期分為新建(New)、可執行(Runnable)、阻塞(Blocked)、等待(Waiting)、超時等待(Timed_Waiting)和終止(Terminated)這6種狀態。

在系統執行過程中不斷有新的執行緒被建立,老的執行緒在執行完畢後被清理,執行緒在排隊獲取共享資源或者鎖時將被阻塞,因此執行中的執行緒會在可執行、阻塞、等待狀態之間來回切換。

執行緒的具體狀態轉化流程如圖所示。

0 2

執行緒生命週期狀態轉化流程

(1) 呼叫new方法新建一個執行緒,這時執行緒處於新建狀態。

(2) 呼叫start方法啟動一個執行緒,這時執行緒處於可執行狀態。可執行狀態中又分:就緒(Ready)和執行中(Running)兩種狀態。處於就緒狀態的執行緒等待執行緒獲取CPU資源,在等待其獲取CPU資源後執行緒會執行run方法進入執行中狀態;正在執行的執行緒在呼叫了yield方法或失去處理器資源時,會再次進入就緒狀態。

(3) 正在執行中的執行緒在執行了sleep方法、I/O阻塞、等待同步鎖、等待通知、呼叫suspend方法等操作後,會掛起並進入阻塞狀態。阻塞狀態的執行緒由於出現sleep時間已到、I/O方法返回、獲得同步鎖、收到通知、呼叫resume方法等情況,會再次進入可執行狀態中的就緒狀態,等待CPU時間片的輪詢。該執行緒在獲取CPU資源後,會再次進入執行狀態。

(4)當執行緒呼叫了Object.wait ()、Object.join()、LockSupport.park()後執行緒進入等待狀態。等待狀態的執行緒呼叫Object.notify ()、Object. notifyAll()、LockSupport.unpark(Thread)方法後會再次進入可執行狀態。

(5) 當可執行狀態的執行緒呼叫Thread.sleep(long)、Object.wait(long)、Thread.join(long)、LockSupport.parkNanos()、LockSupport.parkUntil()時執行緒會進入超時等待狀態。當超時等待的執行緒出現超時時間到、等待進入synchronized方法、等待進入synchronized塊或者呼叫Object.notify ()、Object. notifyAll()、LockSupport.unpark(Thread)時會再次進入可執行狀態。

(6) 處於可執行狀態的執行緒,在呼叫run方法或call方法正常執行完成、呼叫stop方法停止執行緒或者程式執行錯誤導致異常退出時,會進入終止狀態。

0 3

執行緒生命週期詳解

  • 新建狀態(New)

在Java中使用new關鍵字建立一個執行緒,新建立的執行緒將處於新建狀態。在建立執行緒時主要是為執行緒分配記憶體並初始化其成員變數的值。

  • 就緒狀態:Runnable

新建的執行緒物件在呼叫start方法之後將轉為可執行狀態。執行狀態中又分:就緒(Ready)和執行中(Running)兩種狀態。就緒狀態指的是JVM完成了方法呼叫棧和程式計數器的建立,等待該執行緒的排程和執行。

就緒狀態的執行緒在競爭到CPU的使用權並開始執行run方法的執行緒執行體時,會轉為執行中狀態,處於執行中狀態的執行緒的主要任務就是執行run方法中的邏輯程式碼。

  • 阻塞狀態:Blocked

執行中的執行緒會主動或被動地放棄 CPU 的使用權並暫停執行,此時該執行緒將轉為阻塞狀態,直到再次進入可執行狀態,才有機會再次競爭到CPU使用權並轉為執行狀態。阻塞狀態分為如下三種。

(1)等待阻塞: 在執行狀態的執行緒呼叫o.wait方法時,JVM會把該執行緒放入等待佇列(Waitting Queue)中,執行緒轉為阻塞狀態。

(2)同步阻塞: 在執行狀態的執行緒嘗試獲取正在被其他執行緒佔用的物件同步鎖時,JVM會把該執行緒放入鎖池(Lock Pool)中,此時執行緒轉為阻塞狀態。

(3)其他阻塞: 執行狀態的執行緒在執行Thread.sleep(long ms)、Thread.join()或者發出I/O請求時,JVM會把該執行緒轉為阻塞狀態。直到sleep()狀態超時、Thread.join()等待執行緒終止或超時,或者I/O處理完畢,執行緒才重新轉為可執行狀態。

  • 等待狀態:Waiting

當執行緒呼叫了Object.wait()、Thread.join()、LockSupport.park()會進入等待狀態。處於等待狀態的執行緒正在等待另一個執行緒執行指定的操作。例如,呼叫Object.wait()的一個執行緒物件正在等待另一個執行緒呼叫該物件的Object.notify()或Object.notifyAll()。呼叫thread .join()的執行緒正在等待指定的執行緒退出。

  • 超時等待狀態:Timed_Waiting

超時等待和等待狀態的不同是,超時等待狀態的執行緒經過超時時間後會自動喚醒。當執行緒呼叫了Thread.sleep ()、Object.wait(long)、Thread.join(long)、LockSupport.parkNanos()、LockSupport.parkUntil()後執行緒會進入超時等待狀態。

  • 執行緒終止:Terminated

執行緒在以如下三種方式結束後轉為終止狀態。

 執行緒正常結束: run方法或call方法執行完成。

◎  執行緒異常退出: 執行中的執行緒丟擲一個Error或未捕獲的Exception,執行緒異常退出。

◎  手動結束: 呼叫執行緒物件的stop方法手動結束執行中的執行緒(該方式會瞬間釋放執行緒佔用的同步物件鎖,導致鎖混亂和死鎖,不推薦使用)。

本文節選自 《Offer來了:Java面試核心知識點精講(第2版)》

  • 超強Java面試寶典

  • 超詳盡Java知識點速查手冊

  • Java面試官的超趁手Java題庫參考書

  • 一書在手,Java我有

本書講解Java面試中常被問及的核心知識點,涉及Java基礎、Java併發程式設計、JVM、Java高併發網路程式設計、Spring基礎、Netflix的原理及應用、Spring Cloud Alibab的原理及應用、資料結構、Java中常用演算法的原理及其Java實現、關係資料庫及分散式事務、分散式快取的原理及應用、ZooKeeper的原理及應用、Kafka的原理及應用、Elasticsearch的原理及應用、設計模式的概念及其Java實現

本書內容全面、細緻,既可幫助讀者迅速查詢Java知識點,也可幫助讀者完善其Java知識體系;不但可以作為Java面試知識速通手冊,也可以作為Java程式設計師的案頭手冊

送書環節

送書規則:

送書規則:

掃下方二維碼,提前加Tom哥微信,我會在 9月22日 18:00 釋出一條朋友圈,點讚的第 66、188 位,免費包郵送書《Offer來了: Java面試核心知識點精講(第2版)》

說明:文章底部無留言,中獎資格順延下一位小夥伴