閱讀138 返回首頁    go 京東網上商城


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

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

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

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

image.png

圖: 采用https://fastthread.io/生成的狀態圖展示了哪些線程被哪些線程阻塞

BLOCKED

Java文檔官方定義**BLOCKED**狀態是:“這種狀態是指一個阻塞線程在等待monitor鎖。”

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

這就是**BLOCKED**狀態。用技術術語講,你是線程**T1**,你老婆是線程**T2**而鎖是車。**T1**被**BLOCKED**在鎖(例子裏的車)上,因為**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**狀態?哪一個線程被阻塞了?誰在阻塞別人?哪一個對象被鎖了?這些都是很重要的度量分析線程狀態的東西。這些線程分析的細節都可以很容易地用線上分析工具https://fastthread.io/完成。

最後更新:2017-09-04 10:32:26

  上一篇:go  redis4.0之RDB-AOF混合持久化
  下一篇:go  [翻譯]Macvlan 網絡驅動入門