Java并發編程的藝術(四)——線程的狀態
來源:程序員人生 發布時間:2017-02-03 15:15:15 閱讀次數:3673次
線程的狀態
初始態:NEW
創建1個Thread對象,但還未調用start()啟動線程時,線程處于初始態。
運行態:RUNNABLE
在Java中,運行態包括就緒態 和 運行態。
- 就緒態
- 該狀態下的線程已取得履行所需的所有資源,只要CPU分配履行權就可以運行。
- 所有就緒態的線程寄存在就緒隊列中。
- 運行態
- 取得CPU履行權,正在履行的線程。
- 由于1個CPU同1時刻只能履行1條線程,因此每一個CPU每一個時刻只有1條運行態的線程。
阻塞態
- 當1條正在履行的線程要求某1資源失敗時,就會進入阻塞態。
- 而在Java中,阻塞態專指要求鎖失敗時進入的狀態。
- 由1個阻塞隊列寄存所有阻塞態的線程。
- 處于阻塞態的線程會不斷要求資源,1旦要求成功,就會進入就緒隊列,等待履行。
PS:鎖、IO、Socket等都資源。
等待態
- 當前線程中調用wait、join、park函數時,當前線程就會進入等待態。
- 也有1個等待隊列寄存所有等待態的線程。
- 線程處于等待態表示它需要等待其他線程的唆使才能繼續運行。
- 進入等待態的線程會釋放CPU履行權,并釋放資源(如:鎖)
超時等待態
- 當運行中的線程調用sleep(time)、wait、join、parkNanos、parkUntil時,就會進入該狀態;
- 它和等待態1樣,其實不是由于要求不到資源,而是主動進入,并且進入后需要其他線程喚醒;
- 進入該狀態后釋放CPU履行權 和 占有的資源。
- 與等待態的區分:到了超時時間后自動進入阻塞隊列,開始競爭鎖。
終止態
線程履行結束后的狀態。
線程狀態轉換圖

初始態——>就緒態
當線程對象調用start()方法時就會進入就緒態,若就緒隊列沒有線程,則直接進入運行態。
就緒態——>運行態
由系統調用完成。
就緒態<——運行態
- 調用Thread.yield()函數
- 由系統調用完成(當線程時間片用完)
運行態——>阻塞態
當線程要求鎖失敗時進入阻塞態。
阻塞態——>就緒態
阻塞隊列中的線程會不斷檢查鎖是不是可用,1旦可用就進入就緒隊列。
運行態——>等待態
- 調用Object.wait()方法
- wait方法必須在同步塊內部;
- 必須由同步塊的鎖對象調用;
- 必須由notify方法和wait方法必須由同1個鎖對象調用
- 調用Thread.join()方法
- 調用LockSupport.park()方法
等待態——>就緒態
某1個線程調用了 鎖對象.notify()方法,并且等待的線程其實不需要鎖
等待態——>阻塞態
鎖對象.notify()方法,并且等待的線程需要鎖同步。
注意點
- wait()方法會釋放CPU履行權 和 占有的鎖。
- sleep(long)方法僅釋放CPU使用權,鎖依然占用;線程被放入超時等待隊列,與yield相比,它會使線程較長時間得不到運行。
- yield()方法僅釋放CPU履行權,鎖依然占用,線程會被放入就緒隊列,會在短時間內再次履行。
- wait和notify必須配套使用,即必須使用同1把鎖調用;
- wait和notify必須放在1個同步塊中
- 調用wait和notify的對象必須是他們所處同步塊的鎖對象。
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈