Java 幾種線程狀態之間的相互關係

Java Thread 可能處在如下幾種狀態

Java Doc 裏經過一個枚舉類型 Enum<Thread.State> 來定義。面試

線程能夠處於如下狀態之一:
圖片描述工具

  • NEW 還沒有啓動的線程處於此狀態。
  • RUNNABLE 在Java虛擬機中執行的線程處於此狀態。
  • BLOCKED 被阻塞等待監視器鎖定的線程處於此狀態。
  • WAITING 無限期等待另外一個線程執行特定操做的線程處於此狀態。
  • TIMED_WAITING 正在等待另外一個線程執行最多指定等待時間的操做的線程處於此狀態。
  • TERMINATED 已退出的線程處於此狀態。

線程在給定時間點只能處於一種狀態。這些狀態是虛擬機狀態,不反映任何操做系統線程狀態。spa

經過示例而不是Java doc中給出的正式定義,能夠很容易地理解任何使人困惑的概念。若是它們是現實生活中的例子,它可能更具備相關性。我想分享一些可能有助於理解這些線程狀態的現實例子。操作系統

transitive-graph.PNG

http://fastthread.io 生成的傳遞圖,顯示哪些線程阻塞了哪些線程線程

BLOCKED 阻塞

Java doc正式將BLOCKED狀態定義爲:「阻塞等待監視器鎖的線程處於此狀態。」對象

現實生活中的例子:今天你要去面試。這是您求之不得的工做,這是您過去幾年一直瞄準的目標。你早上醒來,準備好了,穿上你最好的衣服,在鏡子前面看起來很敏銳。如今你走出你的車庫,意識到你的妻子已經開車了。在這種狀況下,你只有一輛車,那麼會發生什麼?在現實生活中,可能會發生鬥爭:-)。在這裏你被阻止,由於你的妻子已經開車了。你將沒法參加面試。圖片

這是BLOCKED狀態。用技術術語解釋它,你是線程T1,你的妻子是線程T2,鎖是汽車。T1在鎖(即汽車)上被阻擋,由於T2已經得到了這個鎖。get

提示:線程在等待監視器鎖進入同步塊/方法或在調用Object#wait()方法後從新輸入同步塊/方法時,將進入BLOCKED狀態。同步

WAITING 等候

Java doc正式將WAITING狀態定義爲:「無限期等待另外一個線程執行特定操做的線程處於此狀態。」虛擬機

現實生活中的例子:讓咱們說幾分鐘後你的妻子帶着車回家了。如今你意識到面試的時間已經到了,並且到達那裏還有很長的路要走。所以,您將全部動力都放在汽車的油門踏板上。當容許的速度限制僅爲60英里/小時時,您以100英里/小時的速度行駛。你不走運,交通警察看到你超過限速,他把你拉到路邊。如今你進入WAITING狀態,個人朋友。你中止開車,坐在車裏閒逛,直到警察調查你,而後讓你走。基本上,在他讓你離開以前,你會陷入等待狀態。

用技術術語解釋它,你是線程T1,警察是線程T2。你釋放鎖(即你中止開車),而後進入等待狀態。直到警察(即T2)讓你離開,你將陷入這種等待狀態。

提示:線程在調用如下方法之一時將進入WAITING狀態:

  • Object#wait() 未指定超時時間
  • Thread#join() 未指定超時時間
  • LockSupport#park()

在對象上調用Object.wait()的線程處於WAITING狀態,直到另外一個線程調用該對象上的Object.notify()或Object.notifyAll()。調用Thread.join()的線程處於WAITING狀態,以使指定的線程終止。

TIMED_WAITING 指定時間的等待

Java doc正式將TIMED_WAITING狀態定義爲:「等待另外一個線程在指定的等待時間內執行操做的線程處於此狀態。」

現實生活中的例子: 儘管全部的戲劇性,你在採訪中表現得很是好,給每一個人留下了深入的印象並獲得了這份高薪工做。(恭喜!)你回到家裏,告訴你的鄰居關於這份新工做,以及你對此感到很是興奮。你的朋友說他也在同一棟辦公樓工做。他建議大家兩個應該一塊兒開車。你認爲這是一個好主意。因此在工做的第一天,你去他家。你把車停在他家門口。你等了10分鐘,但你的鄰居仍然沒有出來。你繼續開始上班,由於你不想在第一天被推遲。如今這是TIMED_WAITING。

用技術術語解釋它,你是線程T1,你的鄰居是線程T2。你釋放鎖定(即中止駕駛汽車)並等待長達 10分鐘。若是你的鄰居T2在10分鐘內沒出來,你就開始再次開車了。

提示:線程在調用如下方法之一時將進入TIMED_WAITING狀態:

  • Thread#sleep()
  • Object#wait() 指定超時時間
  • Thread#join() 指定超時時間
  • LockSupport#parkNanos()
  • LockSupport#parkUntil()

結論

當有人在分析線程轉儲時,理解這些不一樣的線程狀態是相當重要的。處於RUNNABLE,BLOCKED,WAITING和TIMED_WATING狀態的線程數是多少?哪些線程被阻止?誰阻止了他們?用於鎖定的對象是什麼?這些是在線程轉儲中要分析的一些重要指標。這些詳細的線程轉儲分析能夠經過在線工具輕鬆完成,例如:http://fastthread.io/

相關文章
相關標籤/搜索