自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

面試官沒想到,一個 Java 線程生命周期,我可以扯半小時

開發(fā) 后端
聰明的你肯定也發(fā)現(xiàn)了,不管是操作系統(tǒng),還是 Java 或者 C# 都有線程的概念。在它們之間,關(guān)于線程的生命周期這一部分,肯定是有相同之處的,否則的話,操作系統(tǒng)自己一套生命周期流程, Java 又有自己的一套, C# 又有自己的一套,而且相互之間還要能夠互相配合,這種成本想想就大的不行對吧。

 本文轉(zhuǎn)載自微信公眾號「 Java極客技術(shù)」,作者鴨血粉絲 。轉(zhuǎn)載本文請聯(lián)系Java極客技術(shù)公眾號。

面試官:你不是精通 Java 并發(fā)嗎?從基礎(chǔ)的 Java 線程生命周期開始講講吧。

好的,面試官。吧啦啦啦...

如果要說 Java 線程的生命周期的話,那我覺得就要先說說操作系統(tǒng)的線程生命周期

因為 JVM 是跑在操作系統(tǒng)上面的嘛,所以是繞不過去的,而且可以說, Java 語言中的線程本質(zhì)上就是操作系統(tǒng)的線程

聰明的你肯定也發(fā)現(xiàn)了,不管是操作系統(tǒng),還是 Java 或者 C# 都有線程的概念。在它們之間,關(guān)于線程的生命周期這一部分,肯定是有相同之處的,否則的話,操作系統(tǒng)自己一套生命周期流程, Java 又有自己的一套, C# 又有自己的一套,而且相互之間還要能夠互相配合,這種成本想想就大的不行對吧

所以咱們就來看看,通用的線程生命周期都有啥

先直接上張圖(阿粉這次的圖,可還行?):

可以看到,主要有 new , ready , running , waiting , terminated 5 種狀態(tài)

其中:

  • new 只是說,這個線程被創(chuàng)建了,但是還不允許分配 CPU 執(zhí)行。因為這個狀態(tài)只是說明你在編程語言層面被創(chuàng)建了,操作系統(tǒng)層面還沒有被創(chuàng)建,肯定就談不上分配 CPU 執(zhí)行了
  • ready 這個狀態(tài)是說,在操作系統(tǒng)層面已經(jīng)成功創(chuàng)建了,所以接下來就是等待分配 CPU 執(zhí)行了。還記得那句經(jīng)典的嘛?ready ?go !
  • running 的狀態(tài),相信你就知道了,我都已經(jīng) ready 了,此時如果再給我分配一下 CPU 我是不是就可以 go 了?那不就是 running 狀態(tài)了嘛
  • waiting 狀態(tài),就是線程在 running 狀態(tài)的時候,突然發(fā)現(xiàn),哎,我需要進行一下 I/O 操作,或者需要等待某個事件發(fā)生(比如說需要某個條件變量),這個時候是不是就不能再繼續(xù) happy 的 running 了。那咋辦?waiting 一下唄
    • 那你都 waiting 了,占用的 CPU 資源是不是應(yīng)該釋放掉?所以說, waiting 狀態(tài)的線程是永遠沒有機會獲得 CPU 使用權(quán)的
    • 你是不是一聽「永遠沒有機會」這幾個字就給嚇壞了,我該不會永遠沒有機會執(zhí)行了吧。放心吧,你不是在 waiting 嘛,等你 wait 的事件發(fā)生了,就可以繼續(xù)到 running 狀態(tài)
  • 當整個線程執(zhí)行完畢,或者出現(xiàn)異常的時候,就進入了 terminated 狀態(tài),也就是線程的使命就完成啦,處于 terminated 狀態(tài)的線程不會再切換到其他狀態(tài)了

通用的線程生命周期以及它們之間是如何切換的,到這里,應(yīng)該就比較清楚了

接下來咱們看看 Java 線程的生命周期,在這個基礎(chǔ)上是怎么做的優(yōu)化,有什么區(qū)別

Java 線程的生命周期

咱們先來瞅瞅源碼定義的狀態(tài)(為了突出重點,我把注釋都去掉了):

  1. public enum State { 
  2.  NEW, 
  3.  RUNNABLE, 
  4.  BLOCKED, 
  5.  WAITING, 
  6.  TIMED_WAITING, 
  7.  TERMINATED; 

能夠清楚的看到,在源碼中定義了 6 種線程狀態(tài),剛才的通用狀態(tài)有幾種來著?5 種對吧,現(xiàn)在是 6 種。

這 6 種是干啥的?剛才的 5 種狀態(tài)以及它們之間的切換我搞清楚了,這 6 種狀態(tài)它們之間又是怎么切換的呢?

別急,阿粉這么貼心,肯定也是畫好了一張圖的:

這 6 個狀態(tài)咱們也是分別來看:

  • NEW 到 RUNNABLE ,應(yīng)該是挺容易理解的,就是 thread 調(diào)用了 start 方法
    • Java 剛創(chuàng)建出來的 Thread 對象就是 NEW 狀態(tài),創(chuàng)建 Thread 對象主要有兩種方法,一種是繼承 Thread 對象,重寫 run() 方法,一種是實現(xiàn) Runnable 接口,重寫 run() 方法,并將該實現(xiàn)類作為創(chuàng)建 Thread 對象的參數(shù)
    • 但是還記得嘛, NEW 只是說,這個線程在編程語言層面創(chuàng)建了,在操作系統(tǒng)層面還沒有創(chuàng)建,那當然就不會被操作系統(tǒng)調(diào)度了對不對,就更談不上執(zhí)行了
    • 所以 Java 線程如果想要執(zhí)行的話,就必須轉(zhuǎn)換到 RUNNABLE 狀態(tài),也就是 thread 調(diào)用 start 方法
  • RUNNABLE 與 BLOCKED ,如果線程等待 synchronized 的隱式鎖時,就會從 RUNNABLE 狀態(tài)轉(zhuǎn)到 BLOCKED 狀態(tài)。因為 synchronized 修飾的方法/代碼塊同一時刻只允許一個線程執(zhí)行,所以其他線程就只能等待了唄,當?shù)却木€程獲得 synchronized 隱式鎖時,就會從 BLOCKED 狀態(tài)轉(zhuǎn)到 RUNNABLE 狀態(tài)
    • 在這里有沒有個疑問?就是線程在 wait 一個條件發(fā)生時,在操作系統(tǒng)層面線程會轉(zhuǎn)到 waiting 狀態(tài),那么在 JVM 層面呢?在 JVM 層面, Java 線程狀態(tài)是不會發(fā)生變化的。也就是這個時候 Java 線程的狀態(tài)依然是 RUNNABLE 狀態(tài)
  • RUNNABLE 與 WAITING 狀態(tài)轉(zhuǎn)換,我感覺圖已經(jīng)說得很好了,在這里不再贅述
  • RUNNABLE 與 TIMED_WAITING 狀態(tài)轉(zhuǎn)換,我感覺圖已經(jīng)說得很好了,在這里也不再贅述,仔細觀察下會發(fā)現(xiàn), TIMED_WAITING 與 WAITING 相比,就是多了超時參數(shù),畢竟 TIMED_WAITING 是有時限等待嘛
  • RUNNABLE 到 TERMINATED ,這個過程比較好理解,線程執(zhí)行完 run() 方法之后,就自動到 TERMINATED 狀態(tài)了,當然了如果在執(zhí)行 run() 方法過程中有異常拋出,也會導(dǎo)致線程終止
    • 有時候我們可能需要強制中斷 run() 方法的執(zhí)行,怎么辦呢?是使用 stop() 方法還是 interrupt() 方法呢?正確的姿勢是調(diào)用 interrupt() 方法
    • stop() 方法會真的殺死線程,不給線程一點兒喘息的機會,如果被殺死的線程持有 synchronized 隱式鎖,那就再也不會釋放掉這個鎖了,接下來的線程也就沒辦法獲得 synchronized 隱式鎖,是不是特別危險?同樣 suspend() 和 resume() 這兩個方法也是不建議使用
    • interrupt() 方法相比于 stop() 方法就溫柔很多,它只是通知線程后續(xù)的操作可以不用去執(zhí)行了,線程可以選擇執(zhí)行現(xiàn)在就不執(zhí)行,當然也可以選擇再執(zhí)行一段時間后再停止,或者我就不聽你的,非要執(zhí)行完,都沒關(guān)系, interrupt() 只是通知一下你而已。就比如你要做火車去一個地方,突然通知你這個火車晚點了,你可以選擇無視這個通知繼續(xù)等待,或者選擇另外一趟高鐵,但是不管你做什么,和火車站都沒啥關(guān)系,它通知的責任盡到了

看到這里應(yīng)該就比較清楚了吧

在 Java 線程生命周期中, RUNNABLE 狀態(tài)是將 ready 和 running 兩種狀態(tài)合并在了一起,而 BLOCKED , WAITING , TIMED_WAITING 這三種狀態(tài)其實就是 waiting 狀態(tài),也就是線程要等待某些事件發(fā)生,才能繼續(xù)向下執(zhí)行下去

關(guān)于 Java 線程的生命周期,到這里就說完啦

畫個圖 + 講解,和面試官扯半小時應(yīng)該沒問題吧?

 

責任編輯:武曉燕 來源: Java極客技術(shù)
相關(guān)推薦

2020-05-13 14:35:47

HashMap面試官Java

2023-01-17 17:54:47

MQ數(shù)據(jù)丟失

2020-05-22 11:00:22

單例Java代碼

2021-08-12 06:52:02

谷歌面試ArrayList

2025-03-11 01:28:16

2021-09-28 13:42:55

Chrome Devwebsocket網(wǎng)絡(luò)協(xié)議

2009-06-18 13:32:39

Java線程生命周期

2021-01-27 18:13:35

日志nginx信息

2009-06-29 18:03:15

Java多線程線程的生命周期

2021-10-20 07:18:51

微信小程序函數(shù)

2010-07-14 10:48:37

Perl線程

2023-10-26 08:25:35

Java線程周期

2017-12-26 15:41:26

2018-01-26 23:23:23

JDBC MySQL數(shù)據(jù)庫

2021-06-02 11:10:09

PythonWeb可視化

2018-06-27 14:23:38

機器學(xué)習人工智能入門方法

2017-03-16 15:27:10

面試官測試技術(shù)

2012-01-16 09:00:56

線程

2022-04-08 08:26:03

JavaHTTP請求

2012-12-28 13:47:36

Raspberry PGeek
點贊
收藏

51CTO技術(shù)棧公眾號