Java執行緒的狀態

超人汪小建發表於2019-03-02

執行緒擁有自己的生命週期,一條執行緒從建立到執行完畢的過程即是執行緒的生命週期,此過程可能在不同時刻處於不同的狀態,執行緒到底有多少種狀態?不同狀態之間是如何轉化的?

對於執行緒的狀態的分類並沒有嚴格的規定,只要能正確表示狀態即可,如圖,先看其中一種狀態分類,一個執行緒從建立到死亡可能會經歷若干個狀態,但在任意一個時間點執行緒只能處於其中一種狀態,總共包含五個狀態:新建(new)、可執行(runnable)、執行(running)、非可執行(not runnable)、死亡(dead)。

這裡寫圖片描述

執行緒的狀態的轉化可以由程式控制,通過某些API可以達到轉化效果,例如Thread類的start、stop、sleep、suspend、resume、wait、notify等方法(stop、suspend、resume等方法因為容易引起死鎖問題而早已被棄用)。

  • 新建(new):一個執行緒被建立了但未被啟動就處於新建狀態,即在程式中使用new MyThread();建立的執行緒例項就處於此狀態。
  • 可執行(runnable):建立的執行緒例項呼叫start()方法後便進入可執行狀態,處於此狀態的執行緒並不是說一定處於執行狀態,Java多執行緒使用的執行緒排程策略是搶佔式排程,每個可執行執行緒輪著獲取CPU時間片,可以虛擬想象成有一個可執行執行緒池,start()方法把執行緒放進可執行執行緒池中,CPU按一定規則一個個執行池裡的執行緒。
  • 執行(running):當可執行執行緒獲取到CPU執行時間片即進去了執行狀態。
  • 非可執行(not runnable):執行中的執行緒因某種原因暫時放棄CPU的使用權,可能是因為執行了掛起、睡眠或等待等操作,在執行I/O操作時由於外部裝置速度遠低於處理器速度也可能導致執行緒暫時放棄CPU使用權,在獲取物件的同步鎖過程中如果同步鎖先被別的執行緒佔用同樣可能導致執行緒暫時放棄CPU。
  • 死亡(dead):執行緒執行完run()方法實現的任務,或因為異常導致退出任務,執行緒進入死亡狀態後將不可再轉換成其他狀態。

將非可執行(not runnable)狀態繼續細分,如圖,新建、可執行、執行、死亡四個狀態的定義和轉化與前面的一樣,重點看非可執行狀態引申出來的三個狀態:阻塞(blocked)、同步鎖(locked)、等待(waiting)。

這裡寫圖片描述

  • 阻塞(blocked):阻塞由阻塞事件觸發,執行緒處於阻塞狀態將放棄CPU的使用權,暫時停止執行。一般執行緒執行了sleep()、join()方法,或發出了I/O請求,執行緒就將處於阻塞狀態,假如sleep()執行的睡眠結束、join()執行的等待中斷超時、I/O請求結束,則將重新回到可執行狀態,等待分配CPU。
  • 同步鎖(locked):假如一個執行緒準備呼叫一個同步方法,而同步方法對應的物件正被其他執行緒佔用,此時執行緒就將進入同步鎖狀態。實際上,Java中的每個object物件都有一個monitor,此monitor負責對同步域在併發時的獨佔處理,即一個執行緒呼叫某物件的同步方法時,JVM將檢測改物件的monitor是否已被佔用,如果沒有被佔用,執行緒則得到monitor佔有權,繼續執行該物件的同步方法,否則執行緒將被扔進一個等待執行緒佇列排隊,直到monitor被釋放後,所有等待的執行緒繼續競爭monitor佔有權,搶到monitor佔有權後才進入可執行狀態等待CPU的分配,才有資格執行同步方法。
  • 等待(waiting):執行中的執行緒執行了wait()方法後就進入等待狀態。一個物件執行了wait()方法同樣將使執行緒進入該物件的等待執行緒佇列,同時它還將釋放物件鎖,即放棄monitor的佔有權。只有在其他執行緒中對該物件呼叫notify()、notifyAll()方法時才會喚醒等待執行緒佇列中的執行緒,notify是隨機喚醒等待佇列中的一個執行緒,而nofityAll則是喚醒所有等待佇列中的執行緒,所有執行緒被喚醒後將對該物件的monitor佔有權競爭,獲取到佔有權的執行緒才能轉化為可執行狀態,等待分配CPU往下執行,其他執行緒則繼續等待。

-------------推薦閱讀------------

我的2017文章彙總——機器學習篇

我的2017文章彙總——Java及中介軟體

我的2017文章彙總——深度學習篇

我的2017文章彙總——JDK原始碼篇

我的2017文章彙總——自然語言處理篇

我的2017文章彙總——Java併發篇


跟我交流,向我提問:

這裡寫圖片描述

公眾號的選單已分為“讀書總結”、“分散式”、“機器學習”、“深度學習”、“NLP”、“Java深度”、“Java併發核心”、“JDK原始碼”、“Tomcat核心”等,可能有一款適合你的胃口。

為什麼寫《Tomcat核心設計剖析》

歡迎關注:

這裡寫圖片描述

相關文章