BLOCKED,WAITING,TIMED_WAITING有什麼區別?-用生活的例子解釋

時序發表於2017-09-04

翻譯原文地址:
https://dzone.com/articles/difference-between-blocked-waiting-timed-waiting-e

BLOCKED,WAITING和TIMED_WAITING是很重要的執行緒狀態,但是經常對我們造成困擾。如果需要分析執行緒dump必須要對其有一定的理解。使用生活的例子,本文將每個狀態變成了簡單的例子。

與正式的Java文件定義相比,任何讓人費解的概念都可以用簡單的例子來理解。如果用真實生活中的例子,就更好理解了。我想分享一些真實生活的例子來幫助理解這些執行緒狀態。

image.png

圖: 採用http://fastthread.io/生成的狀態圖展示了哪些執行緒被哪些執行緒阻塞

BLOCKED

Java文件官方定義BLOCKED狀態是:“這種狀態是指一個阻塞執行緒在等待monitor鎖。”

真實生活例子:今天你要去面試。這是你夢想的工作,你已經盯著它多年了。你早上起來,準備好,穿上你最好的外衣,對著鏡子打理好。當你走進車庫發現你的老婆已經把車開走了。在這個場景,你只有一輛車,所以怎麼辦?在真實生活中,可能會打架:-)。 現在因為你老爸把車開走了你被BLOCKED了。你不能去參加面試。

這就是BLOCKED狀態。用技術術語講,你是執行緒T1,你老婆是執行緒T2而鎖是車。T1BLOCKED在鎖(例子裡的車)上,因為T2已經獲取了這個鎖。

小貼士:當執行緒呼叫Object#wait()方法進入一個synchronized塊/方法或重進入一個synchronized鎖/方法時會等待獲取monitor鎖。

WAITING

Java文件官方定義WAITING狀態是:“一個執行緒在等待另一個執行緒執行一個動作時在這個狀態”

真實生活例子:再看下幾分鐘後你的老婆開車回家了。現在你意識到快到面試時間了,而開車過去很遠。所以你拼命地踩油門。限速120KM/H而你以160KM/H的速度在開。很不幸,一個交警發現你超速了,讓你停到路邊。現在你進入了WAITING狀態。你聽下車坐在那等著交警過來檢查你並放行。基本上,只有等他讓你走,你被卡在WAITING狀態了。

用技術術語來講,你是執行緒T1而交警是執行緒T2。你釋放你的鎖(例子中你停下了車),並進入WAITING狀態,直到警察(例子中T2)讓你走,你陷入了WAITING狀態。

小貼士:當執行緒呼叫以下方法時會進入WAITING狀態:

  1. Object#wait() 而且不加超時引數
  2. Thread#join() 而且不加超時引數
  3. LockSupport#park()

在物件上的執行緒呼叫了Object.wait()會進入WAITING狀態,直到另一個執行緒在這個物件上呼叫了Object.notify()或Object.notifyAll()方法才能恢復。一個呼叫了Thread.join()的執行緒會進入WAITING狀態直到一個特定的執行緒來結束。

TIMED_WAITING

Java文件官方定義TIMED_WAITING狀態為:“一個執行緒在一個特定的等待時間內等待另一個執行緒完成一個動作會在這個狀態”

真實生活例子:儘管充滿戲劇性,你在面試中做的非常好,驚豔了所有人並獲得了高薪工作。(祝賀你!)你回家告訴你的鄰居你的新工作並表達你激動的心情。你的朋友告訴你他也在同一個辦公樓裡工作。他建議你坐他的車去上班。你想這不錯。所以第一天,你走到他的房子。在他的房子前停好你的車。你等了10分鐘,但你的鄰居沒有出現。你繼續開自己的車去上班,這樣你不會在第一天就遲到。這就是TIMED_WAITING.

用技術術語來解釋,你是執行緒T1而你的鄰居是執行緒T2。你釋放了鎖(這裡是停止開車)並等了足足10分鐘。如果你的鄰居T2沒有來,你繼續開車。

小貼士:呼叫了以下方法的執行緒會進入TIMED_WAITING

  1. Thread#sleep()
  2. Object#wait() 並加了超時引數
  3. Thread#join() 並加了超時引數
  4. LockSupport#parkNanos()
  5. LockSupport#parkUntil()

結論

當人們分析thread dump時,理解這些不同的執行緒狀態很關鍵。
有多少執行緒在RUNNABLE,BLOCKED,WAITING和TIMED_WAITING狀態?哪一個執行緒被阻塞了?誰在阻塞別人?哪一個物件被鎖了?這些都是很重要的度量分析執行緒狀態的東西。這些執行緒分析的細節都可以很容易地用線上分析工具http://fastthread.io/完成。


相關文章