多線程——線程狀態

目錄

1.線程的狀態

1.1 NEW

1.2 RUNNABLE

1.3?BLOCKED

1.4 WAITING

1.5 TIMED_WAITING

1.6 TERMINATED

2.線程狀態的相互轉換


在上期的學習中,已經理解線程的啟動(start())、休眠(sleep())、中斷(interrupt())和等待(join())等核心概念。通過這些操作,線程會在不同的狀態之間切換。那么,線程在這些過程中究竟經歷了哪些狀態?它們是如何轉換的?這是本期要探討的問題。

在前面談到進程狀態時,主要講了就緒狀態和阻塞狀態,這是兩個經典的狀態。在線程中,線程的狀態有六種,分別是:NEWRUNNABLEBLOCKEDWAITINGTIMED_WAITINGTERMINATED。這幾個狀態在 Java 中屬于枚舉類型,可以用代碼實現查看這些狀態:

public class Demo14 {public static void main(String[] args) {for (Thread.State state : Thread.State.values()) {System.out.println(state);}}
}

下面將對它們一 一介紹。

1.線程的狀態

1.1 NEW

小帥對自己的女神小美仰慕已久,小帥同學打算好好打扮自己去追求女神小美,但是小帥心里膽怯,所以到目前為止,只是停留在仰慕的狀態。此時小帥心里有追求女神小美的想法,但還沒開始行動 start(),屬于 NEW 狀態。

NEW:是指一個線程已經被創建(new),但是還沒開始執行的狀態,稱新建狀態,也就是這個時候還沒用調用 start()

public class Demo14 {public static void main(String[] args) {Thread thread = new Thread(() -> {//.........},"小帥");System.out.println(thread.getName() + ":" + thread.getState());//thread.start();//這里已經注釋,沒有調用start()}
}

運行結果:

1.2 RUNNABLE

終于,小帥下定決心,開啟了對小美的追求之路。每天會和女神聊聊天,偶爾會約女神吃飯,也會給女神送禮物。此時小帥已經有實際行動了 start(),女神小美可能會立即回復,也有可能在忙其他事情,屬于 RUNNABLE 狀態。

RUNNABLE是指線程正在 JVM 中正在執行或者準備執行的狀態,成可運行狀態。也就是線程已經創建,并且調用了 start() 方法,新建線程開始執行。

public class Demo14 {public static void main(String[] args) {Thread thread = new Thread(() -> {},"小帥");System.out.println("調用start()前:" + thread.getName() + ":" + thread.getState());thread.start();System.out.println("調用start()后:" + thread.getName() + ":" + thread.getState());}
}

運行結果:

1.3?BLOCKED

小帥追求一段時間后,小美也對他有所回應,于是小帥想約小美周末一起看個電影,但是小美說你約晚了,周末要和好閨蜜一起去逛街。此時小帥不能約到小美,因為小美被閨蜜占用了,屬于BLOCKED 狀態。

BLOCKED:是指線程處于阻塞狀態。這個是由于鎖導致的,在下期線程安全問題會有講解,這里先做一個了解。

public class Demo14 {public static void main(String[] args) throws InterruptedException {Object locker = new Object();Thread thread1 = new Thread(() -> {synchronized (locker){while (true) {System.out.println("閨蜜和小美在逛街....");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}},"閨蜜");Thread thread2 = new Thread(() -> {synchronized (locker){System.out.println("小帥約小美看電影....");}},"小帥");thread1.start();thread2.start();}
}

這里需要借助 jconsole 查看狀態,關于 jconsole 在前面的文章《多線程——認識Thread類和創建線程》有講。狀態如下:

可以看到,“小帥”這個線程的狀態就是 BLOCKED。

1.4 WAITING

時間來到第二周,雖然上周小帥沒有約到小美一起看電影,但是啊,小帥沒有放棄,于是小帥再次鼓氣勇氣再約女神一次,這次女神說這周末目前沒有安排,但是這周工作有點忙,具體要看后面的時間安排,于是說“等我有時間聯系你把”,但是小美并沒有說會多久聯系。于是呢,小帥覺得有點希望的,所以就一直等啊等,不分白天黑夜的一直在等女神的消息。此時,小帥一直等,沒有期限的等待就屬于 WAITING 狀態。

WAITING是指某線程無限期等待其他線程執行特定任務的狀態,稱等待狀態。也就是說需要其他線程完成一定的任務后,這個狀態才能進行,需要調用?join()?方法。

public class Demo14 {public static void main(String[] args) throws InterruptedException {Thread thread1 = new Thread(() -> {while (true) {try {System.out.println("等待小美聯系中....");Thread.currentThread().join();} catch (InterruptedException e) {throw new RuntimeException(e);}}},"小帥");Thread thread2 = new Thread(() -> {System.out.println("回復了小帥的邀約....");},"小美");thread1.start();thread1.join();thread2.start();}
}

借助 jconsole 查看狀態,狀態如下:

1.5 TIMED_WAITING

如果上面例子中,如果小美對小帥說“我這周比較忙,不一定有時間,我兩三天內再回復你能不能出去看電影吧。”此時,小帥就會等小美的回復,但不會一直等下去了,最多就等三天,此時的等待就屬于 TIMED_WAITING。

TIMED_WAITING是指線程在指定的時間內等待,這個等待有期限,稱計時等待狀態

public class Demo14 {public static void main(String[] args) throws InterruptedException {Object locker = new Object();Thread thread1 = new Thread(() -> {while (true) {System.out.println("等待小美聯系中....");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}},"小帥");Thread thread2 = new Thread(() -> {System.out.println("回復了小帥的邀約....");},"小美");thread1.start();thread1.join(5000);//這里設置等待5秒thread2.start();}
}

借助 jconsole 查看狀態,狀態如下:

1.6 TERMINATED

小帥和小美在聯系一段時間后,小帥和小美決定彼此并不合適,所以并沒有在一起,小帥也放棄了追求小美,至此小帥對仰慕已久的女神的追求徹底結束了,屬于 TERMINATED 狀態。

TERMINATED是指線程執行完畢的狀態,稱終止狀態。

public class Demo14 {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(()->{//....},"小帥");thread.start();thread.join();System.out.println(thread.getName() + "對女神的追求結束了... 現在的狀態是:" + thread.getState());}
}

運行結果:

2.線程狀態的相互轉換

雖然線程狀態的相互轉換看似復雜,但主要是理解各個狀態的含義以及是怎么發生的,這對于在后續的多線程學習中是非常重要的,尤其是調試程序找 bug 的時候,想要在多線程程序中進行調試,理解線程的狀態是非常重要的,并且還需會使用 jconsole 或者其他根據查看當前線程的狀態,比如前文使用 jconsole 查看狀態時,還可以看到一些其他信息比如當前的狀態是發生在哪一行。在這張轉換圖里,看到了一些方法比如 wait(),這個也是等待的方法,用法和 join() 類似,但在這里不深入講解,在后面會專門寫一期 wait() 的用法,以及 synchronized() { } 等都會詳細解析介紹到。


本期主要介紹多線程的線程狀態,主要過程狀態是NEW -> RUNNABLE -> TERMINATED,然后在這個過程中發生一些狀態轉換,主要理解每個狀態的含義并可以借助一些工具如? jconsole 查看線程狀態。

從多線程的創建學習到現在,我們也理解了多線程的優勢,但是那多線程一定很安全嗎?是不是多線程可以隨意使用呢?在 Java 基礎學習中,我們談到?StringBuffer 和 StringBuilder 時,說 StringBuffer 是線程安全的,而 StringBuilder 是線程不安全的。可見線程會存在安全問題,為什么會有線程安全問題以及導致線程安全問題的原因是什么?

欲知后事如何,且聽下回分解!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/95409.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/95409.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/95409.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

IMX6ULL的設備樹文件簡析

先分析一個完整的設備樹,是怎么表達各種外設信息的。以imux6ull開發板為例進行說明。這個文件里就一個設備信息才這么點內容,是不是出問題了?當然不是,我們知道dts文件是可包含的,所以,最終形成的一個完整文…

【ARM】PACK包管理

1、 文檔目標對 pack 包的管理有更多的了解。2、 問題場景客戶在安裝了過多的 pack 包導致軟件打開比較慢,各種 pack 包顏色的區別,及圖標不同。3、軟硬件環境1)、軟件版本:Keil MDK 5.392)、電腦環境:Wind…

【Kubernetes】知識點4

36. 說明K8s中Pod級別的Graceful Shutdown。答:Graceful Shutdown(優雅關閉)是指當 Pod 需要終止時,系統給予運行中的容器一定的時間來等待業務的應用的正常關閉(如保存數據、關閉連接、釋放資源等)&#x…

Paraverse平行云實時云渲染助力第82屆威尼斯電影節XR沉浸式體驗

今年,Paraverse平行云實時云渲染平臺LarkXR,為享有盛譽的第82屆威尼斯國際電影節(8月27日至9月6日)帶來沉浸式體驗。 LarkXR助力我們的生態伙伴FRENCH TOUCH FACTORY,實現ITHACA容積視頻的XR交互演示,從意大…

大數據開發計劃表(實際版)

太好了!我將為你生成一份可打印的PDF版學習計劃表,并附上項目模板與架構圖示例,幫助你更直觀地執行計劃。 由于當前環境無法直接生成和發送文件,我將以文本格式為你完整呈現,你可以輕松復制到Word或Markdown中&#xf…

GitLab 18.3 正式發布,更新多項 DevOps、CI/CD 功能【二】

沿襲我們的月度發布傳統,極狐GitLab 發布了 18.3 版本,該版本帶來了通過直接轉移進行遷移、CI/CD 作業令牌的細粒度權限控制、自定義管理員角色、Kubernetes 1.33 支持、通過 API 讓流水線執行策略訪問 CI/CD 配置等幾十個重點功能的改進。下面是對部分重…

Docker學習筆記(二):鏡像與容器管理

Docker 鏡像 最小的鏡像 hello-world 是 Docker 官方提供的一個鏡像,通常用來驗證 Docker 是否安裝成功。 先通過 docker pull 從 Docker Hub 下載它。 [rootdocker ~]# docker pull hello-world Using default tag: latest latest: Pulling from library/hello-wor…

STM32F103C8T6開發板入門學習——寄存器和庫函數介紹

學習目標:STM32F103C8T6開發板入門學習——寄存器和庫函數介紹學習內容: 1. 寄存器介紹 1.1 存儲器映射 存儲器本身無固有地址,是具有特定功能的內存單元。它的地址是由芯片廠商或用戶分配,給存儲器分配地址的過程就叫做存儲區映射…

【CouponHub項目開發】使用RocketMQ5.x實現延時修改優惠券狀態,并通過使用模板方法模式重構消息隊列發送功能

在上個章節中我實現了創建優惠券模板的功能,但是,優惠券總會有過期時間,我們怎么去解決到期自動修改優惠券狀態這樣一個功能呢?我們可以使用RocketMQ5.x新出的任意定時發送消息功能來解決。 初始方案:首先在創建優惠券…

Claude Code SDK 配置Gitlab MCP服務

一、MCP配置前期準備 (一)創建個人令牌/群組令牌 我這里是創建個人令牌,去到首頁左上角,點擊頭像——>偏好設置——>訪問令牌——>添加新令牌 (二)配置mcp信息 去到魔塔社區,點擊mc…

Eclipse 常用搜索功能匯總

Eclipse 常用搜索功能匯總 Eclipse 提供了多種搜索功能,幫助開發者快速定位代碼、文件、類、方法、API 等資源。以下是詳細的使用方法和技巧。 一、常用搜索快捷鍵快捷鍵功能描述Ctrl H打開全局搜索對話框,支持文件、Java 代碼、任務等多種搜索。Ctrl …

關于Spring的一些理解

Spring整體結構:Spring實際運行場景:基礎 Spring啟動過程 傳統Spring: (1)初始化準備階段 (2)容器創建與注入 (3)Bean工廠后置處理 (4)Bean工廠后…

Windows右下角系統托盤圖標快速顯示或隱藏

系統托盤指的是Windows電腦桌面右下角的區域,包括時間、wifi(網絡)、音量、電源、輸入法、一些程序/應用等。啟動了應用后,Windows會把部分應用的圖標顯示或隱藏在系統托盤區。我們可以根據需要快速顯示或隱藏相關應用&#xff0c…

Kotlin編程學習記錄2

Kotlin編程學習記錄2——條件與循環 條件語句:if 與 when ? Kotlin 的控制流把“表達式優先”作為設計原則——if、when 不只是控制語句,都可以作為表達式使用并返回值,這影響了日常代碼風格(更函數式、可組合)。筆…

印度物聯網崛起:政策紅利下的千億藍海與本土化博弈

印度物聯網市場正處于快速發展階段,2025年市場規模預計達到200億美元,主要得益于政府"數字印度"計劃和智能城市項目的推動。蜂窩物聯網連接數在2024年同比增長34%,2025年Q1增速進一步提升至32%,其中智能電表部署和資產追蹤應用成為核心驅動力。然而,市場也面臨著…

html學習:

ok,今天準備學一下html&#xff0c;花費點時間整理一下&#xff1a; HTML標簽的語法格式 HTML 中的標簽就像關鍵字一樣&#xff0c;每個標簽都有自己的語義&#xff08;含義&#xff09;。 HTML 標簽的語法格式 屬性↓ <div class"begin">cyx</div>↑…

CRYPT32!PkiAsn1Decode函數分析的一個例子

第一部分&#xff1a; 0: kd> g Breakpoint 35 hit CRYPT32!PkiAsn1Decode: 001b:75c9af0c 55 push ebp 1: kd> kc# 00 CRYPT32!PkiAsn1Decode 01 CRYPT32!PkiAsn1DecodeAndAllocInfo 02 CRYPT32!PkiAsn1DecodeAndAllocInfoEx 03 CRYPT32!Asn1InfoDecode…

大模型蒸餾、大模型微調、RAG

前言&#xff1a; 有很多同學想學習大模型開發&#xff0c;又無從下手&#xff0c;網上一搜&#xff0c;鋪天蓋地的付費課程。又不想當韭菜&#xff0c;打破認知障礙&#xff0c;通過自學&#xff0c;改變自己&#xff0c;改變世界&#xff01; 一、大模型蒸餾、微調、RAG的適…

25高教社杯數模國賽【E題保姆級思路+問題分析】

注&#xff1a;本內容由”數模加油站“ 原創出品&#xff0c;雖無償分享&#xff0c;但創作不易。 歡迎參考teach&#xff0c;但請勿抄襲、盜賣或商用。 E 題 AI輔助智能體測 《國家學生體質健康標準》的頒布&#xff0c;有效地促進了大中小學生關注自身體質健康的發展&#xf…

基于單片機車內換氣溫度檢測空氣質量檢測系統Proteus仿真(含全部資料)

全套資料包含&#xff1a;Proteus仿真源文件keil C語言源程序AD原理圖流程圖元器件清單說明書等 資料下載&#xff1a; 通過網盤分享的文件&#xff1a;資料分享 鏈接: 百度網盤 請輸入提取碼 提取碼: tgnu 目錄 資料下載&#xff1a; Proteus仿真功能 項目文件資料&#…