成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

IO 阻塞期間,為什么線程狀態顯示 RUNNABLE?

開發 前端
比較 Java 線程與操作系統線程,可以發現 Java 線程狀態沒有可運行狀態。也就是說 Java 線程 RUNNABLE 狀態包括了操作系統的可運行狀態與運行狀態。一個處于??RUNNABLE??狀態 Java 線程,在操作系統層面狀態可能為可運行狀態,正在等待系統分配 CPU 使用權。

使用 Java 阻塞 I/O 模型讀取數據,將會導致線程阻塞,線程將會進入休眠,從而讓出 CPU 的執行權,直到數據讀取完成。這個期間如果使用 jstack 查看線程狀態,卻可以發現Java 線程狀態是處于 RUNNABLE,這就和上面說的存在矛盾,為什么會這樣?

上面的矛盾其實是混淆了操作系統線程狀態與 Java 線程狀態。這里說的線程阻塞進入休眠狀態,其實是操作系統層面線程實際狀態。而我們使用 jstack 查看的線程狀態卻是 JVM 中的線程狀態。

線程是操作系統中一種概念,Java 對其進行了封裝,Java 線程本質上就是操作系統的中線程,其狀態與操作系統的狀態大致相同,但還是存在一些區別。

下面首先來看我們熟悉的 Java 線程狀態。

一、Java 線程狀態

Java 線程狀態定義在 Thread.State 枚舉中,使用  thread#getState 方法可以獲取當前線程的狀態。

Thread.State 狀態如下圖:

圖片圖片

image

可以看到 Java 線程總共存在 6 中狀態,分別為:

  • NEW(初始狀態)
  • RUNNABLE(運行狀態)
  • BLOCKED(阻塞狀態)
  • WATTING(等待狀態)
  • TIMED_WAITING(限時等待狀態)
  • TERMINATED(終止狀態)

每個使用new Thread()剛創建出線程實例狀態處于NEW狀態,一旦調用thread.start(),線程狀態將會變成 RUNNABLE

其中,RUNNABLE狀態的線程在進入由synchronized修飾的方法或代碼塊前將會嘗試獲取一把隱式的排他鎖,一旦獲取不到,線程狀態將會變成BLOCKED,等待獲取鎖。一旦有其他線程釋放這把鎖,線程成功搶到該鎖,線程狀態就將會從BLOCKED轉變為RUNNABLE狀態。

而,處于WATTING狀態的線程將會一直處于無限期的等待狀態,需要等待其他線程喚醒。總共存在三種方法將會使線程從 RUNNABLE變成WATTING

  • Object#wait:線程在獲取到synchronized隱式鎖后,顯示的調用Object#wait()方法。這種情況下該線程將會讓出隱式鎖,一旦其他線程獲取到該鎖,且調用了Object.notify()object.notifyAll(),線程將會喚醒,然后變成RUNNABLE
  • Thread#joinjoin方法是一種線程同步方法。假設我們在main方法中執行Thread A.join()方法,main線程狀態就會變成WATTING。直到A線程執行完畢,main線程才會再變成RUNNABLE
  • LockSupport#park()LockSupport是 JDK 并發包里重要對象,很多鎖的實現都依靠該對象。一旦調用 LockSupport#park(),線程就將會變為 WATTING 狀態。如果需要喚醒線程就需要調用 LockSupport#unpark,然后線程狀態重新變為 RUNNABLE

TIMED_WAITINGWATTING 功能一樣,只不過前者增加限時等待的功能,一旦等待時間超時,線程狀態自動變為 RUNNABLE。以下幾種情況將會觸發這種狀態:

  • 1.Thread#sleep(long millis)
  • 2.占有synchronized隱式鎖的線程調用Object.wait (long timeout)方法
  • 3.Thread#join (long millis)
  • 4.LockSupport#parkNanos (Object blocker, long deadline)
  • 5.LockSupport#parkUntil (long deadline)

線程一旦執行結束或者線程執行過程發生異常且未正常捕獲處理,狀態都將會自動變成TERMINATED

Java 線程 6 種狀態看起來挺復雜的,但其實上面 BLOCKEDWATTINGTIMED_WAITING,都會使線程處于休眠狀態,所以我們將這三類都歸類為休眠狀態。這么分類的話,Java 線程生命周期就可以簡化為下圖:

圖片

二、通用操作系統線程狀態

上面講完 Java 系統的線程狀態,我們來看下通用操作系統的線程狀態。操作系統線程狀態可以分為初始狀態,可運行狀態,運行狀態,休眠狀態以及終止狀態,如下圖:

圖片

這 5 中狀態詳細情況如下:

  • 1.初始狀態,這時候線程剛被創建,還不能分配 CPU 。
  • 2.可運行狀態,線程等待系統分配 CPU ,從而執行任務。
  • 3.運行狀態,操作系統將 CPU 分配給線程,線程執行任務。
  • 4.休眠狀態,運行狀態下的線程如果調用阻塞 API,如阻塞方式讀取文件, 線程狀態就將變成休眠狀態。這種情況下,線程將會讓出 CPU 使用權。休眠結束,線程狀態將會先變成可運行狀態。
  • 5.線程執行結束或者執行過程發生異常將會使線程進入終止狀態,這個狀態下線程使命已經結束。

三、對比兩者線程狀態

比較 Java 線程與操作系統線程,可以發現 Java 線程狀態沒有可運行狀態。也就是說 Java 線程 RUNNABLE 狀態包括了操作系統的可運行狀態與運行狀態。一個處于RUNNABLE狀態 Java 線程,在操作系統層面狀態可能為可運行狀態,正在等待系統分配 CPU 使用權。

另外 Java 線程細分了操作系統休眠狀態,分成了BLOCKEDWATTINGTIMED_WAITING三種。

當線程調用阻塞式 API,線程進入休眠狀態,這里指的是操作系統層面的。從 JVM 層面,Java 線程狀態依然處于 RUNNABLE 狀態。JVM 并不關心操作系統線程實際狀態。從 JVM 看來等待 CPU 使用權(操作系統線程狀態為可運行狀態)與等待 I/O (操作系統線程狀態處于休眠狀態)沒有區別,都是在等待某種資源,所以都歸入 RUNNABLE 狀態。


責任編輯:武曉燕 來源: Java極客技術
相關推薦

2024-06-19 10:26:36

非阻塞IO客戶端

2023-12-06 07:28:47

阻塞IO異步IO

2021-10-13 06:49:15

網絡 IO

2022-11-08 17:39:27

MySQLkilled

2020-02-11 15:30:51

Redis快照數據庫

2024-01-09 18:09:43

模型方式DMA

2009-06-29 18:00:05

Java多線程Runnable接口創建線程

2021-06-07 12:11:20

JavaRunning狀態

2025-01-14 08:42:34

IO流程序語句

2010-03-16 18:59:15

Java Runnab

2023-03-21 08:02:36

Redis6.0IO多線程

2023-01-03 19:11:09

CPUI/O速度

2023-12-20 14:35:37

Java虛擬線程

2024-11-28 11:07:50

線程JVM操作系統

2020-04-22 20:35:02

HashMap線程安全

2022-07-26 07:14:20

線程隔離Thread

2024-01-19 08:42:45

Java線程字符串

2023-12-13 09:45:49

模型程序

2017-04-20 13:33:12

代碼開源PySonar

2020-04-29 14:10:44

Java線程池編程語言
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩久久久久久 | 国产成人高清视频 | 久久亚洲综合 | 午夜影院在线观看视频 | 国产精品久久久久久中文字 | 午夜视频在线免费观看 | 欧美一级片在线 | 日韩国产在线 | 99re在线 | 久久久夜夜夜 | 免费av毛片 | 国产97在线视频 | 四虎影院美女 | 亚洲视频在线观看 | 不卡一区二区三区四区 | 日韩av三区 | 天天夜碰日日摸日日澡 | 午夜黄色影院 | 国产免费看 | 精品日韩一区 | 欧美日韩国产精品一区 | 日韩精品视频中文字幕 | 国产精品18久久久久久久 | 久久精点视频 | 在线天堂免费中文字幕视频 | 亚洲欧洲日韩精品 中文字幕 | 九九99九九精彩46 | 91免费在线视频 | 欧美日韩综合精品 | 麻豆91精品91久久久 | 成人国产在线视频 | 精品国产一区二区三区观看不卡 | 国产欧美一区二区三区日本久久久 | 99久久精品免费看国产免费软件 | 日韩欧美在线不卡 | 午夜综合 | 日韩欧美在线免费 | 一区二区三区在线观看免费视频 | 亚洲精品丝袜日韩 | 91中文字幕在线观看 | 久久国产综合 |