天天看點

圖解Java線程狀态轉換線程狀态小結曆史好文推薦關于我

大家好,我是阿星,好久不見,歡迎來到

Java

并發程式設計系列番外篇線程狀态轉換,内容通俗易懂,請放心食用。

線程狀态

先來個開場四連問

  • Java

    線程狀态有幾個?
  • Java

    線程狀态是如何轉換?
  • Java

    線程狀态轉換什麼情況會進入鎖的等待隊列?
  • Java

    線程狀态轉換什麼情況會進入鎖的同步隊列?

一提到

Java

線程狀态,不少讀者立馬想到線程狀态轉換圖,但細想,印象又不深刻,隻記得有那麼幾個狀态。

再要你說出

Java

線程狀态是如何轉換的,腦子裡可能就如下圖一樣,已經是一團漿糊了。

圖解Java線程狀态轉換線程狀态小結曆史好文推薦關于我

别慌,阿星為了幫讀者大大們理清楚上面的問題,會一步一步的把線程狀态轉換圖給畫出來,讓讀者大大們真正的了解Java線程狀态轉換。

首先線程的狀态可以分為

6

态或

7

态,具體狀态如下

6态

  • New

    :建立狀态
  • Runnable

    :可運作狀态
  • Terminated

    :終止狀态
  • Waiting

    :等待狀态
  • TimedWaiting

    :逾時等待狀态
  • Blocked

    :阻塞狀态

7态

  • New

    :建立狀态
  • Ready

    :就緒狀态
  • Running

    :運作狀态
  • Terminated

    :終止狀态
  • Waiting

    :等待狀态
  • TimedWaiting

    :逾時等待狀态
  • Blocked

    :阻塞狀态

其實6态與7态差别不大,隻不過

7

态把

Runnable

可運作狀态,拆解成了

Ready

就緒狀态與

Running

運作狀态。

阿星以

7

态為例,來逐漸講解它們之間是如何轉換的。

建立狀态(New)

我們可以通過實作

Runnable

接口或繼承

Thread

聲明一個線程類,

new

一個執行個體後,線程就進入了建立狀态。

圖解Java線程狀态轉換線程狀态小結曆史好文推薦關于我
一個剛誕生的線程,處于建立狀态。

就緒狀态(Ready)

線程對象建立成功後,調用該線程的

start()

函數,線程進入就緒狀态,該狀态的線程進入可運作線程池中,等待擷取

C P U

的使用權。

圖解Java線程狀态轉換線程狀态小結曆史好文推薦關于我
線程表示,我已經準備好了,此時我是就緒狀态,快選我吧~

運作狀态(Running)

此時線程排程程式正在從可運作線程池中選擇一個線程,該線程進入運作狀态。

換句話說,線程擷取到了

C P U

時間片。

圖解Java線程狀态轉換線程狀态小結曆史好文推薦關于我

還沒完呢,當線程時間片用完或調用的

yield()

函數,該線程回到就緒狀态。

圖解Java線程狀态轉換線程狀态小結曆史好文推薦關于我
作為一名運氣好的線程,我進入了運作狀态,但是運氣用完了,我還得回到就緒狀态。

終止狀态(Terminated)

線程繼續運作,直到執行結束或執行過程中因異常意外終止都會使線程進入終止狀态。

線程一旦終止,就不能複生,這是不可逆的過程。

圖解Java線程狀态轉換線程狀态小結曆史好文推薦關于我
線程的人生迎來了終點,可能一帆風順過完一生,也可能英年早逝令人惋惜。

等待狀态(Waiting)

運作狀态的線程執行wait()、join()、LockSupport.park()任意函數,該線程進入等待狀态。

其中

wait()

join()

函數會讓J V M把該線程放入鎖等待隊列。

處于這種狀态的線程不會被配置設定C P U執行時間,它們要等待被主動喚醒,否則會一直處于等待狀态。

圖解Java線程狀态轉換線程狀态小結曆史好文推薦關于我

如果我們要喚醒線程怎麼辦呢?

執行

LockSupport.unpark(t)

函數喚醒指定線程,該線程回到就緒狀态。

而通過

notify()、notifyAll()、join線程執行完畢

方式,會喚醒鎖等待隊列的線程,出隊的線程回到就緒狀态。

圖解Java線程狀态轉換線程狀态小結曆史好文推薦關于我
線程的人生迎來了劫難,聽信小人之言,跑去菲律賓做打工,結果被黑工廠扣下,隻希望警察叔叔能早日解救我出去。

逾時等待狀态(Timed waiting)

逾時等待與等待狀态一樣,唯一的差別就是多了逾時機制,不會一直等待被其他線程主動喚醒,而是到達指定時間後會自動喚醒。

以下函數會觸發進入逾時等待狀态

  • wait(long)
  • join(long)
  • LockSupport.parkNanos(long)
  • LockSupport.parkUtil(long)
  • sleep(long)

其中

wait(long)、join(long)

函數會讓J V M把線程放入鎖等待隊列。

圖解Java線程狀态轉換線程狀态小結曆史好文推薦關于我

後面的喚醒劇情就和等待狀态如出一轍,就多了逾時時間到了,自動喚醒的動作。

圖解Java線程狀态轉換線程狀态小結曆史好文推薦關于我
從菲律賓回國後的線程,也做起了違法的勾當,最終被警察抓捕,好在隻判了5年,熬一熬就可以出來了。

阻塞狀态(Blocked)

運作狀态的線程擷取同步鎖失敗或發出

I/O

請求,該線程進入阻塞狀态。

如果是擷取同步鎖失敗

J V M

還會把該線程放入鎖的同步隊列。

圖解Java線程狀态轉換線程狀态小結曆史好文推薦關于我

同步鎖被釋放時,鎖的同步隊列會出隊所有線程,進入就緒狀态。

I/O

處理完畢時,該線程重新回到就緒狀态。

圖解Java線程狀态轉換線程狀态小結曆史好文推薦關于我
出獄後的線程,後面的人生一直都是磕磕碰碰,就沒順利過,大家要引以為戒。

小結

相信讀者大大們跟着阿星的思路來,已經掌握了線程狀态的知識,以後面試官問這類問題,也可以吊打一番,最後放一張簡化的線程轉換圖為本文畫上句号。

圖解Java線程狀态轉換線程狀态小結曆史好文推薦關于我

曆史好文推薦

  • 圖文并茂的聊聊ReentrantReadWriteLock的位運算
  • 通俗易懂的ReentrantLock,不懂你來砍我
  • 萬字長文 | 16張圖解開AbstractQueuedSynchronizer
  • 寫給小白看的LockSupport
  • 13張圖,深入了解Synchronized
  • 由淺入深CAS,小白也能與BAT面試官對線
  • 小白也能看懂的Java記憶體模型
  • 保姆級教學,22張圖揭開ThreadLocal
  • 程序、線程與協程傻傻分不清?一文帶你吃透!
  • 什麼是線程安全?一文帶你深入了解

關于我

阿星是一個熱愛技術的

Java

程式猿,公衆号 「程式猿阿星」 定期分享有趣有料的精品原創文章!

圖解Java線程狀态轉換線程狀态小結曆史好文推薦關于我

非常感謝各位小哥哥小姐姐們能看到這裡,原創不易,文章有幫助可以關注、點個贊、分享與評論,都是支援(莫要白嫖)!

願你我都能奔赴在各自想去的路上,我們下篇文章見。